首页 > 解决方案 > 为什么转义闭包需要我们明确地引用 self ?

问题描述

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 说 Swift 通过强迫你写 self 来表明保留周期的可能性。那么在使用转义闭包时是否存在保留周期的可能性?还是有任何其他原因为什么我们必须在标记为转义的闭包中明确引用 self ?

为什么在另一种情况下(非逃逸闭包),没有保留周期的可能性?

提前致谢。

标签: swift

解决方案


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

斯坦福讲座是对的,但为什么会发生这种情况?将 self 放入闭包中可能会变成一个引用循环,其中对象永远不会放开。您可以通过使用弱自我或未知自我来避免这种情况。但是,您应该只使用弱自我或未知自我,以避免强引用循环。

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


推荐阅读