Swift-“弱自我”可选绑定,可避免保留周期

时间:2019-12-17 11:51:32

标签: swift

这似乎有些奇怪,但是下面的代码块通常可以在URLSessionWebSocketTask框架的Foundation类的方法的完成处理程序主体中遇到。

这是一个例子:

func send(data: Data) {

    let dataMessage = URLSessionWebSocketTask.Message.data(data)

    webSocketTask.send(dataMessage) { [weak self] error in

        guard let self = self else { return }

        if let error = error {

            self.delegate?.onError(connection: self, error: error)
        }
    }
}

此捕获绑定的确切含义是什么?

2 个答案:

答案 0 :(得分:2)

@escaping之类的send闭包中,self默认被捕获为强引用。

因此self强烈引用send,而send强烈引用self(在delegate行中)。这称为保留周期,会导致内存泄漏,因为闭包和代表self的实例在执行闭包后都不会被释放。

为避免保留周期,您必须将self捕获为weak(它是可选的)或unowned。它确保闭包消失时将{/ {1}}释放。您不需要非转义的闭包(例如self闭包)中的捕获组。

DispatchQueue语句检查guard是否仍然有效。在其他情况下,您可以轻松使用可选链接,例如self

答案 1 :(得分:1)

默认情况下,闭包将捕获具有强引用的作用域属性。这意味着,只要有对对象的“强”引用,就不会释放该对象。为了避免这种情况,可以为闭包捕获的self设置一个弱引用。

类比:

强引用:

您将您的儿子送到面包店买面包,并给他列出了他回来后要做的事情。几分钟后,您接到朋友打来的电话,要求您与他外出,但是由于您的儿子要您待在家里,您无法外出。

弱引用(弱自我): 您将您的儿子送到面包店买面包,然后给他列出他回来后要做的事情。因为您不确定他回来时是否会在家,所以您说:儿子,如果您回来后我不在家,那就什么也不做(警惕,让self = self else {return})< / p>