Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 我应该将自定义单元格的委托作为弱引用的属性吗?_Swift_Delegates_Retain Cycle - Fatal编程技术网

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

Swift 我应该将自定义单元格的委托作为弱引用的属性吗?,swift,delegates,retain-cycle,Swift,Delegates,Retain Cycle,视图控制器代码 class ViewController: UIViewController { deinit { print("ViewController deinitialised") } @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { self.tableView.dataSource = self } f

视图控制器代码

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()
}
我不知道什么是实现在单元格和ViewController之间传递消息的委托模式的合适方法。我知道,如果两个对象强烈地持有彼此的引用,就会有一个保留周期,并且它们不会在应用程序生命周期中被释放

在上面的代码中,ViewController似乎不包含单元格的引用。因此,我认为如果我使用A型协议并在单元格中保留ViewController的强引用,这并不重要

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

更新:

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


现在最大的问题是ViewController是如何保持对单元格的强引用的?那里发生了一些事情

  • 使每个ViewController都符合UITableViewDelegate和UITableViewDatasource是不必要的,因为您已经有了UITableViewController,并且您可能仍然需要重写这些方法。您将在开发生命周期的某个时刻复制代码

  • 代理始终需要是弱引用,以避免保留循环


  • 去初始化过程:

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

    然后,仅清除视图控制器保留的所有其他引用

    父Denit触发器,子Denit触发器,然后在遍历所有Denit之后,最终完成父Denit的释放

    如果有任何子项强烈引用父项。父对象的去初始化永远不会被调用,所有的去初始化过程都会停止。在我们的例子中,因为单元强烈地保留了视图控制器。从未调用ViewController的deinit方法。因此,保持循环。
    下面是对

    的一个很好的解释。另外请注意,由于buttonattaped不能通过self,所以很难知道哪个按钮被点击了。@MatthewSeaman你说得对。这很难说,但再一次。。。无论如何,他可能需要覆盖整个实现。我在这里展示的代码仅用于演示目的。请查看上面的更新。显然,tableView保留了对ViewController的强引用,而不管@IBOutlet是弱引用。这很有趣。我认为真正的问题是在单元格前面的一步:什么是具有强引用的@IBOutlet?如果是ViewController,它如何在内部管理保留周期?再次使用完整的ViewController代码进行更新。