[英]Swift closures and Memory Leaks
由於客戶的要求,我對該項目有立面設計。 我想知道哪種方法消耗的內存最少,哪種方法更好。
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
閉包定義中)。 您可以在閉包中定義捕獲列表來避免這種情況。
捕獲列表中的每個項目都是對weak或unown關鍵字的配對,這些關鍵字與對類實例的引用(例如self)或用某個值初始化的變量(例如委托= self.delegate!)配對。 這些配對寫在一對方括號內,並用逗號分隔。
我認為這是因為tableCellThird屬性對其關閉( rtn:)擁有強烈的引用。
如果您通過self關鍵字捕獲引用,那么它將成為強引用。
因此,您需要使用不帶self關鍵字的屬性,如下所示。
tableCellThird?.cellsNew(rtn: { (cells) in
rtn(cells)
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.