自我何时保留闭包?

问题描述 投票:0回答:2

[我已经读了一段时间的内存管理,我知道当闭包保留self和self保留closure时,我们应该使用[weak self]来打破循环,我的问题是闭包何时保留self以及何时self自我保留关闭?

ios swift memory-management
2个回答
0
投票

这里是一个例子:

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秒钟后完成了加载数据,所以它并未被取消初始化。


0
投票

这通常通常,尽管并非总是如此。

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

  • [thing保留闭包,如果它具有一个或包含一个函数且该函数为闭包的属性。

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

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

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

现实生活中的问题是,这是在您没有意识到的情况下发生的。您知道要保留something,但是您可能没有意识到something是或包含闭包。典型的例子是当您致电

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

该调用返回一个观察者对象,您将其保留下来,以便获得通知。但是,您也要手动调用一个闭包,如果它提到您,则您有一个保留周期,因为您要保留包含提到您的闭包的观察者。

并且还有许多其他类似的常见陷阱。

© www.soinside.com 2019 - 2024. All rights reserved.