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")
}
}
CustomCell代码
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没有直接引用cell&即使TableView的引用很弱,ViewController也会以某种方式保持对单元格的强引用。当我遵循方法A时,即没有声明委托是弱引用。 Cell和ViewController中的deinit方法永远不会被调用。我也检查了仪器。如果我没有将委托声明为弱,那么持久保留计数会不断增加。
现在最大的问题是ViewController如何保持对细胞的强引用?
答案 0 :(得分:1)
那里有几件事。
让每个ViewController都符合UITableViewDelegate和UITableViewDatasource是不必要的,因为你已经有了UITableViewController,你可能还需要覆盖这些方法。您将在开发生命周期的某个时刻复制代码。
委托总是需要作为弱引用来避免保留周期。
答案 1 :(得分:0)
取消初始化流程:
弹出视图控制器时。 然后调用deinit方法。
然后只清除视图控制器所持有的所有其他引用。
父母去掉触发器,孩子的deinit触发器然后遍历所有deinit然后最终完成父母的释放。
如果任何一个孩子强烈引用父母。父的deinit永远不会被调用,所有的deinitialization进程都会停止。在我们的例子中,由于单元格强烈保留视图控制器。 ViewController的deinit方法永远不会被调用。因此保留周期。 以下是retain cycle.
的绝佳解释