簡體   English   中英

快速關閉和內存泄漏

[英]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閉包定義中)。 您可以在閉包中定義捕獲列表來避免這種情況。

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

捕獲列表中的每個項目都是對weak或unown關鍵字的配對,這些關鍵字與對類實例的引用(例如self)或用某個值初始化的變量(例如委托= self.delegate!)配對。 這些配對寫在一對方括號內,並用逗號分隔。

我認為這是因為tableCellThird屬性對其關閉( rtn:)擁有強烈的引用。

如果您通過self關鍵字捕獲引用,那么它將成為強引用。

因此,您需要使用不帶self關鍵字的屬性,如下所示。

tableCellThird?.cellsNew(rtn: { (cells) in
          rtn(cells)
       })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM