【发布时间】:2020-08-01 22:30:54
【问题描述】:
我正在使用自定义 UITableViewCells 填充 UITableView,每个 UITableViewCells 中都有一个按钮。为了检查是否按下了按钮,我使用了委托协议模式。这是我的实现:
protocol MyTableViewCellDelegate {
func didPressButtonInTableView(for indexPath: IndexPath)
}
class MyTableViewCell: UITableViewCell {
lazy var indexPath = (self.superview?.superview as! UITableView).indexPath(for: self)
var delegate: MyTableViewCellDelegate!
@IBAction func buttonPressed(_ sender: Any) {
self.delegate.didPressButtonInTableView(for: self.indexPath!)
}
}
在阅读了一些关于内存管理的内容后,我意识到有时,由于“强引用循环”,持有对父类的引用的子类的实例不会被释放,因为父类和子类都持有互相强烈的引用。我们必须使用weak 关键字来定义一个弱关系,当父类被释放时,子类也会被释放。
所以,我意识到使用委托持有对 UITableView(父类)的强引用。运行一些测试,比如检查 Xcode 调试器中的内存使用情况并在子类中使用 deinit,我意识到这些表视图单元格没有被释放。将协议更改为使用AnyObject,然后将委托设置为weak 解决了该问题。再次运行时,内存使用量并没有持续增加,当我转到不同的视图时,deinit 被调用。
运行 Leaks in Instruments 中的两个版本的代码,在第一种情况下没有内存泄漏,但是,每次加载表视图时,内存都会显着增加。
我的问题是,为什么这没有在 Instruments 中标记为内存泄漏,因为子类使用委托持有对父类的强引用?这与导致 Instruments 捕获泄漏的传统父子字符串引用有什么区别?
【问题讨论】:
标签: ios swift uitableview