【问题标题】:When does a self retain a closure?self 何时保留闭包?
【发布时间】:2020-07-03 07:33:20
【问题描述】:

我一直在阅读内存管理一段时间,我知道当闭包保持自我和自我保持闭包我们应该把[弱自我]打破循环,我的问题是闭包什么时候保持自我,什么时候保持自我保留一个闭包?

【问题讨论】:

    标签: ios swift memory-management


    【解决方案1】:

    通常很明显,但并非总是如此。

    • 如果提及thingthing 的任何属性,闭包将保留thing

    • 如果thing 的属性是或包含函数并且该函数就是闭包,则它会保留闭包。

    我在书中使用的人工示例是:

    class FunctionHolder {
        var function : (() -> ())?
    }
    func testFunctionHolder() {
        let fh = FunctionHolder()
        fh.function = {
            print(fh)
        }
    }
    

    这里,thingfh,一个 FunctionHolder 实例。我们将提及fh 的闭包分配给fhfunction 属性。这是一个保留周期。

    现实生活中的问题是,这种情况会在您没有意识到的情况下发生。你知道你正在保留 something,但你可能没有意识到某事是或包含一个闭包。经典的例子是当你打电话时

    let ob = NotificationCenter.default.addObserver(forName:...
    

    该调用返回一个观察者对象,您保留该对象以便收到通知。但是你也提交了一个调用闭包,如果它提到了你,你就有了一个保留循环,因为你保留了包含提到你的闭包的观察者。

    还有许多其他常见的此类陷阱情况。

    【讨论】:

      【解决方案2】:

      这是一个例子:

      class ViewController: UIViewController {
      
          var data = Data() {
              didSet {
                  // do something
              }
          }
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              Service.loadData { data in
                  self.data = data
              }
              perform(#selector(tryToDismiss), with: self, afterDelay: 0.5)
          }
      
          @objc func tryToDismiss() {
              dismiss(animated: true)
          }
      
          deinit {
              print("ViewController got deinit")
          }
      }
      
      class Service {
      
          static func loadData(completion: @escaping (Data) -> Void) {
              DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                  completion(Data())
              }
          }
      }
      

      您可以看到,即使视图控制器在加载 0.5 秒后被解除,它也没有被取消初始化,因为在 1 秒后完成加载数据的关闭。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-15
        • 2018-10-11
        • 2017-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-20
        相关资源
        最近更新 更多