逃脱关闭捕获强大的链接与否?

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

在我的例子中,我在其他函数中创建实例。在函数结束时,我希望instance2应该是nil,而completionHandlers数组不应该与SomeClass2有强连接,但completionHandlers仍然是链接。

看起来@escaping封闭在内部创建强大的链接。

var completionHandlers: [() -> Void] = []

func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

class SomeClass {
    var x = 10
    func doSomething() {
        let instance2 = SomeClass2()
        instance2.doSomething2()
    }
}

class SomeClass2 {
    var x = 11
    func doSomething2() {
        someFunctionWithEscapingClosure {
            // still exist
            self.x = 77
        }
    }
}

let instance = SomeClass()
instance.doSomething()

completionHandlers.first!()
swift swift3 escaping closures
1个回答
0
投票

来自documentation

如果为类实例的属性分配闭包,并且闭包通过引用实例或其成员来捕获该实例,则将在闭包和实例之间创建一个强引用循环。 Swift使用捕获列表来打破这些强大的参考周期。有关更多信息,请参阅Strong Reference Cycles for Closures

这里没有强大的引用循环,但是提到闭包捕获实例,这就是你的情况。为了防止你可以明确地捕获它:

func doSomething2() {
    someFunctionWithEscapingClosure { [weak self] in
        self?.x = 77
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.