快速关闭和内存泄漏
问题描述:
由于客户的要求,我有一个基于外观的项目设计。我想知道哪种方法具有最少的内存消耗,哪种方法更好。快速关闭和内存泄漏
class ModFirst: NSObject {
func getCells(tableView: UITableView, rtn: @escaping ([Any]?) -> Void) {
print("ModFirst- getCells")
TableCellFirst().cells(tableView: tableView, rtn: { (cells) in
rtn(cells)
})
}
}
class ModThird: NSObject {
lazy var tableCellThird: TableCellThird? = TableCellThird()
func getCellsNew(rtn: @escaping ([Any]?) -> Void) {
print("ModThird - getCellsNew")
self.tableCellThird?.cellsNew(rtn: { (cells) in
rtn(cells)
})
}
deinit {
print("deinit - ModThird")
self. tableCellThird = nil
}
}
以上是两种不同的实现方式。第一种方法立即分配TableCellFirst对象并调用getCells方法。这个实现没有任何内存泄漏。但第二个实现使用惰性变量和deinit,但在使用Instruments进行性能分析时仍然存在内存泄漏。
那么哪种方法是最好的方法,哪种方法在泄漏时更安全?
答
它可能不明显,但在第二种情况下,我有一个很强的参考周期(我猜它在rtn
闭包定义中)。你可以在闭包中定义一个捕获列表来避免这种情况。
在捕获列表中的每个项目是一类实例的引用弱或无主关键字的配对(如自)或可变的一些值进行初始化(例如,委托= self.delegate!)。这些配对写在一对方括号内,用逗号分隔。
答
我想这是因为tableCellThird财产持有强引用其关闭(RTN:)。
如果您通过自我捕获参考关键字,所以它将被持有强烈的参考。
所以你需要使用你的财产没有自我关键字如下。
tableCellThird?.cellsNew(rtn: { (cells) in
rtn(cells)
})
看到这一点:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID48 – KKRocks