我应该将自定义单元格的委托作为弱引用属性吗?

Should I make delegate of custom cell as a weakly referenced proprety?

ViewController代码

class ViewController: UIViewController {
    deinit {
        print("ViewController deinitialised")
    }

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        self.tableView.dataSource = self
    }

    func didTapBlue() {

    }
}

extension ViewController: UITableViewDataSource, CustomCellDelegate {
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("myCell") as! CustomCell
        cell.delegate =  self
        cell.textLabel!.text = "\(indexPath.row)"
        return cell
    }

    func buttonTapped() {
        print("Button tapped")
    }
}

自定义单元格代码

class CustomCell: UITableViewCell {
    deinit {
        print("Cell deinitialised")
    }

    var delegate: CustomCellDelegate! //When protocol Type is A
    // weak prefix when protocol Type is B
    // weak var delegate: CustomCellDelegate!

    @IBAction func buttonClickAction(sender: AnyObject) {
        if let del = self.delegate {
            del.buttonTapped()
        }
    }
}

协议类型 A

protocol CustomCellDelegate{
    func buttonTapped()
}

协议类型 B

protocol CustomCellDelegate: class {
    func buttonTapped()
}

我对在 Cell 和 ViewController 之间传递消息实现委托模式的合适方法感到困惑。我知道如果两个对象强烈地持有彼此的引用,就会有一个保留周期,并且它们在应用程序生命周期内不会被释放。

在上面的代码中,ViewController 似乎没有保存 Cell 的引用。因此,我认为使用类型 A 的协议并在单元格中保留 ViewController 的强引用并不重要。

但是,如果我将委托 属性 声明为弱引用 属性,我的代码会更安全吗?它的含义是什么?

更新:

事实证明,即使 ViewController 没有持有单元格的直接引用,即使 TableView 的引用很弱,ViewController 也会以某种方式持有对单元格的强引用。当我遵循方法 A 时,没有将委托声明为弱引用。 Cell 和 ViewController 中的 deinit 方法永远不会被调用。我也检查了仪器。如果我不将委托声明为弱,持久保留计数会不断增加。

现在最大的问题是 ViewController 如何保持对单元格的强引用?

那里发生了几件事。

  1. 使每个 ViewController 都符合 UITableViewDelegate 和 UITableViewDatasource 是不必要的,因为您已经拥有 UITableViewController 并且您可能无论如何都需要重写这些方法。您可能会在开发生命周期的某个时刻重复代码。

  2. 委托总是需要成为弱引用以避免循环引用。

去初始化过程:

当视图控制器弹出时。 然后调用 deinit 方法。

然后只有视图控制器持有的所有其他引用被清除。

parents deinit触发,child的deinit触发,然后遍历所有deinit,最后parent的deinit释放完成。

如果任何子项强引用父项。 parent 的 deinit 永远不会被调用,所有的去初始化过程都会停止。在我们的例子中,因为单元格强烈保留视图控制器。 ViewController 的 deinit 方法永远不会被调用。因此,保留周期。 这是对 retain cycle.

的很好解释