在我的例子中,我在其他函数中创建实例。在函数结束时,我希望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使用捕获列表来打破这些强大的参考周期。有关更多信息,请参阅Strong Reference Cycles for Closures。
这里没有强大的引用循环,但是提到闭包捕获实例,这就是你的情况。为了防止你可以明确地捕获它:
func doSomething2() {
someFunctionWithEscapingClosure { [weak self] in
self?.x = 77
}
}