【问题标题】:Swift closures and Memory LeaksSwift 闭包和内存泄漏
【发布时间】:2017-11-25 07:14:57
【问题描述】:

由于客户的要求,我有一个基于立面的项目设计。我想知道哪种方法的内存消耗最少,哪种方法更好。

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 进行分析时仍然存在内存泄漏。

那么,在发生泄漏的情况下,哪种方法最好,哪种方法更安全?

【问题讨论】:

标签: ios swift memory-leaks automatic-ref-counting


【解决方案1】:

这可能并不明显,但在第二种情况下你有一个强大的引用循环(我猜它在 rtn 闭包定义中)。您可以在闭包中定义一个捕获列表来避免这种情况。

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

捕获列表中的每一项都是weak 或unowned 关键字与对类实例的引用(例如self)或用某个值初始化的变量(例如delegate = self.delegate!)的配对。这些配对写在一对方括号内,用逗号分隔。

【讨论】:

    【解决方案2】:

    我认为这是因为 tableCellThird 属性持有对其闭包(rtn:)的强引用。

    如果您通过 self 关键字捕获引用,那么它将是强引用。

    因此,您需要使用不带 self 关键字的属性,如下所示。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-12
      • 2013-01-11
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      • 2017-05-11
      • 2019-01-08
      相关资源
      最近更新 更多