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是如何保持对单元格的强引用的?那里发生了一些事情
去初始化过程: 当视图控制器弹出时。 然后调用deinit方法 然后,仅清除视图控制器保留的所有其他引用 父Denit触发器,子Denit触发器,然后在遍历所有Denit之后,最终完成父Denit的释放 如果有任何子项强烈引用父项。父对象的去初始化永远不会被调用,所有的去初始化过程都会停止。在我们的例子中,因为单元强烈地保留了视图控制器。从未调用ViewController的deinit方法。因此,保持循环。
下面是对的一个很好的解释。另外请注意,由于buttonattaped不能通过self,所以很难知道哪个按钮被点击了。@MatthewSeaman你说得对。这很难说,但再一次。。。无论如何,他可能需要覆盖整个实现。我在这里展示的代码仅用于演示目的。请查看上面的更新。显然,tableView保留了对ViewController的强引用,而不管@IBOutlet是弱引用。这很有趣。我认为真正的问题是在单元格前面的一步:什么是具有强引用的@IBOutlet?如果是ViewController,它如何在内部管理保留周期?再次使用完整的ViewController代码进行更新。