为什么转义的闭包要求我们显式地引用self?

时间:2018-11-25 19:20:24

标签: swift

Apple的Swift文档说:

  

用@escaping标记闭包意味着您必须引用self   明确地在封闭内。

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

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

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        someFunctionWithEscapingClosure { self.x = 100 }
        someFunctionWithNonescapingClosure { x = 200 }
    }
}

但是我不明白这背后的原因吗?

在他的斯坦福大学演讲中(我不完全记得哪一个),保罗·黑格蒂(Paul Hegarty)说,斯威夫特通过强迫你写自己来表明保留周期的可能性。那么在使用转义闭包时是否存在保留周期的可能性?还是有其他原因导致我们必须在标记为转义的闭包内显式引用self?

为什么在其他情况下(非转义的闭包)没有保留周期的可能性?

谢谢。

1 个答案:

答案 0 :(得分:2)

Self用于保留/捕获要发送消息的对象的实例。如果您不使用self,那么编译器将不知道将消息发送到哪里

斯坦福大学的演讲是正确的,但是为什么会这样呢?在封闭中拥有自我可能会变成一个参考周期,在这个周期中,对象永远不会放开。您可以通过使用弱自我或未知自我来避免这种情况。您应该只使用弱自我或未知自我,以避免强参考周期。

让我知道这是否可以正确回答您的问题,或者您是否需要更多帮助