首页 > 解决方案 > Swift:嵌套闭包中的自引用

问题描述

我在 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在嵌套的完成处理程序中引用,以及什么应该是最佳实践。谢谢。

标签: swiftcocoakey-value-observingcompletionhandler

解决方案


即使您有一个强引用循环,您也不会看到任何内存泄漏,直到所有其他强引用消失。

例如,如果这个 VC 在整个应用程序生命周期内都处于活动状态,即使闭包捕获了一个强引用循环,它也不会做任何事情。影响将是相同的:VC 将在整个应用程序生命周期内都处于活动状态,无论如何它已经在这样做了。

只有当您有一个强引用循环时,您才能识别内存泄漏,然后尝试通过删除所有其他强引用来取消初始化 VC。


推荐阅读