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

时间:2018-03-06 08:00:31

标签: swift swift3 escaping closures

在我的例子中,我在其他函数中创建实例。在函数结束时,我希望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!()

1 个答案:

答案 0 :(得分:0)

来自documentation

  

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

你在这里没有强大的参考周期,但是提到闭包捕获实例,以及你的情况会发生什么。为了防止你可以明确地捕获它:

func doSomething2() {
    someFunctionWithEscapingClosure { [weak self] in
        self?.x = 77
    }
}