![](/img/trans.png)
[英]Does closure create a strong reference to an object that is created inside closure scope?
[英]convert the reference back to a strong one inside the closure, memory management, swift
我正在嘗試關閉保留周期,如下所示
class Sample {
deinit {
print("Destroying Sample")
}
func additionOf(a: Int, b:Int) {
print("Addition is \(a + b)")
}
func closure() {
dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
self?.additionOf(3, b: 3)
usleep(500)
self?.additionOf(3, b: 5)
}
}
}
后來在某些時候,我正在做
var sample : Sample? = Sample()
sample?.closure()
dispatch_async(dispatch_get_global_queue(0, 0)) {
usleep(100)
sample = nil
}
輸出將是
Addition is 6
Destroying Sample
這是可以理解的,因為self
在做self?.additionOf(3, b:5)
之前是沒有的self?.additionOf(3, b:5)
如果我通過創建另一個引用[weak self]
變量(如下所示)在閉包內部進行了更改
dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.additionOf(3, b: 3)
usleep(500)
strongSelf.additionOf(3, b: 5)
}
這次,輸出是
Addition is 6
Addition is 8
Destroying C
我的問題是為什么在sample = nil
之后, strongSelf
不會出現問題。 是因為它在sample = nil
之前被捕獲在閉包內
讓我們考慮你的第二個例子:
dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.additionOf(3, b: 3)
usleep(500)
strongSelf.additionOf(3, b: 5)
}
這是一種常見的模式,它有效地說“如果self
已被解除分配,立即return
,否則建立一個強大的參考, strongSelf
,並保持這個強大的參考,直到關閉完成。”
所以,在你的例子中,當這個調度塊開始時self
不是nil
,所以一旦我們分配了strongSelf
來引用它,我們現在有兩個強引用這個Sample
對象,原始sample
引用和這個新的strongSelf
引用里面這個關閉。
因此,當你的另一個線程刪除它自己的強引用, sample
,到這個Sample
對象時(通過超出范圍或通過顯式設置sample
為nil
),這個strongSelf
強引用仍然存在,並將保持對象不被釋放(或者至少在此調度塊完成之前。
在上面的評論中,您會問:
我仍然不明白為什么
strongSelf
沒有改變,因為自己nil
...
強引用永遠不會被設置為nil
只是因為其他一些強引用(即使它是原始的強引用)被設置為nil
。 參考設置為nil
行為僅適用於weak
引用,而不適用於強引用。
當你的代碼在第一個線程上執行sample = nil
時,所做的就是刪除一個強引用。 它不會刪除對象或類似的東西。 它只是刪除了它的強大參考。 現在,調度塊有自己的強引用,所有在sample = nil
時發生的事情是,具有兩個強引用的對象現在只剩下一個強引用(調度塊中的strongSelf
引用)。 只有在刪除了最終的強引用時,才會釋放對象並deinit
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.