我试图了解tableview在后台如何工作。
当我呼叫dequeueReusableCell()时,TableView将实例化我的CustomCell来构成一个单元格。就是这样

let cell = CustomCell(style: CustomCell.self, reuseIdentifier: "CustomCell") // Cell type CustomCell.


现在我们有一个cell实例。到目前为止一切都还好。但是,当我尝试使用此单元格时,必须将该单元格向下转换为CustomCell

let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath) as! CustomCell


在上面的示例中,TableView实例化CustomCELLCustomCELL类型。但这实际上是UITableCell的类型。

我的问题是,在TableView实例化CustomCell作为CustomCell类型后,它使CustomCell向上转换为UITableCell,从而使单元格类型变为UITableCell吗?我必须将其转换为CustomCell才能使用。

有人可以向我解释所有事物如何运作吗?
谢谢您的时间!

class CustomCell : UITableViewCell {

    static let identifier = "CustomCell"

    // properties, etc., e.g.:
    private let label = UILabel()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        // here you do the setup, adding subviews, etc., e.g.:
        self.contentView.addSubview(label)
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 4),
            label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),
            label.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 8),
            label.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -8),
        ])
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //other methods, e.g., for configuring the cell, e.g.:
    func configure(withTitle title: String) {
        label.text = title
    }

}


下面的CustomTableController类

class CustomTableController: UITableViewController {

    fileprivate var data: [Model] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 44

        // registering a cell class for reuse is important
        // but it's enough to make it once in viewDidLoad
        tableView.register(CustomCell.self, forCellReuseIdentifier: CustomCell.identifier)

        tableView.reloadData()
    }

    // MARK: Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // here you can dequeue your cell
        let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath) as! CustomCell
        // configure the cell using model, e.g.:
        cell.configure(withTitle: data[indexPath.row].title)
        return cell
    }
}

最佳答案

dequeueReusableCell的函数签名表示它返回UITableViewCell?的一个实例,这就是编译器所知道的全部。

当您针对重用标识符注册单元格子类时,该函数实际上将返回单元格子类的实例。

然后,您可以使用向下运算符as使编译器知道您实际上在运行时期望单元格子类的实例。这将使您可以使用单元格子类的属性。

如果向下转换在运行时失败,那么您将得到nil(针对有条件的向下转换as?)或异常(针对强制向下转换as!

这种行为依赖于面向对象编程中的基本概念。代换。可以将类型T的子类S提供给期望或返回T的任何函数(或由任何函数返回)。

请注意,cellForRowAt被声明为返回UITableViewCell,但允许您返回自定义单元格子类实例。

关于ios - 当我调用dequeueReusableCell()时,TableView会实例化我的CustomCell并将其向上转换到UITableViewCell?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48620733/

10-11 04:35