Swift:嵌套闭包中的自引用

时间:2018-10-22 18:54:41

标签: swift cocoa key-value-observing completionhandler

我正在Swift中使用新的基于块的KVO API来观察属性。 下面是示例代码。

class A: NSObject {
var observerA: NSKeyValueObservation? = nil
var observerB: NSKeyValueObservation? = nil

var property1: CustomObj1?
var property2: CustomObj2?

func doSomething() {

}

func doSomethingElse() {

}

func observeValues() {
    observerA = customObj1.observe(\.property1, options: [], changeHandler: { [weak self] (obj, change) in
        guard let strongSelf = self else { return }
        strongSelf.doSomething()
        strongSelf.observerB = customObj2.observe(\.property2, options: [], changeHandler: { [weak strongSelf] (nestedObj, nestedChange) in
            guard let nestedStrongSelf = strongSelf else { return }
            nestedStrongSelf.doSomethingElse()
        })
    })
}

}

我的问题是我们如何在内部变更处理程序块中引用self。 我可以像上面一样使用它,但看不到任何内存泄漏。但是在内部变更处理程序的“ [weak strongSelf]”中使用self代替strongSelf也不会引起任何问题。这是代码。

func observeValues() {
observerA = self.observe(\.property1, options: [], changeHandler: { [weak self] (obj, change) in
    guard let strongSelf = self else { return }
    strongSelf.doSomething()
    strongSelf.observerB = strongSelf.observe(\.property2, options: [], changeHandler: { [weak self] (nestedObj, nestedChange) in
        guard let nestedStrongSelf = self else { return }
        nestedStrongSelf.doSomethingElse()
    })
})

}

我的问题是,self应该如何在嵌套完成处理程序中被引用,什么是最佳实践?谢谢。

1 个答案:

答案 0 :(得分:0)

即使您拥有强大的参考周期,您也不会看到任何内存泄漏,直到所有其他强大的参考消失为止。

例如,如果该VC在整个应用程序生命周期中都有效,那么即使闭包捕获了强大的参考周期,它也无济于事。效果是一样的:VC在整个应用程序生命周期中都可以运行,无论如何它一直在做。

仅当您具有强引用周期时,您才能够识别内存泄漏,然后尝试通过删除所有其他强引用来取消初始化VC。