这似乎有些奇怪,但是下面的代码块通常可以在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)
}
}
}
此捕获绑定的确切含义是什么?
答案 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>