【发布时间】:2016-08-25 02:49:21
【问题描述】:
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 如何保持对单元格的强引用?
【问题讨论】:
-
我认为真正的问题是单元格之前的一步:什么是具有强引用的@IBOutlet?如果是 ViewController,它如何在内部管理保留周期?
-
再次更新了完整的 ViewController 代码。
标签: swift delegates retain-cycle