[英]Calling dispatchQueue.sync in deinit causes unowned reference of self
在一個類中,我將所有成員讀/寫在串行 dispatchQueue 中以保護多線程訪問。 但是當我在 deinit 中將 [unowned [unowned self]
傳遞給 dispatchQueue 的任務時,我遇到了對self
的 unowned 引用的致命錯誤。
在下面的示例中,在調用self.q.sync{...}
之前,我仍然可以讀取self
並且refCount(self)
在deinit{}
仍然不是 0。 然后在將[unowned self]
傳遞給隊列的任務時立即引發致命錯誤
class Host {
let text = "Hello"
let q = DispatchQueue(label: "workingloop")
deinit {
// `self` is ok to be read
print("begin count: \(CFGetRetainCount(self)), ptr: \(Unmanaged.passUnretained(self).toOpaque())")
self.q.sync { [unowned self] in // <- callstack stop here
print(self.text)
}
// not reach
print("end count: \(CFGetRetainCount(self)), ptr: \(Unmanaged.passUnretained(self).toOpaque())")
}
}
func foo() {
let host = Host()
// <- trigger Host.deinit()
}
begin count: 2, ptr: 0x000000010871fb00
Fatal error: Attempted to read an unowned reference but object 0x10871fb00 was already deallocated 2020-01-13 10:31:11.758734+0800 xctest[29473:2710298] Fatal error: Attempted to read an unowned reference but object 0x10871fb00 was already deallocated
class.deinit{}
是一個特殊的范圍,我們不應該將self
傳遞給另一個線程或任務嗎?
我也嘗試使用[weak self]
傳遞,而self
仍然是nil
。 不知道為什么它的引用計數在另一個任務中達到零。
什么是去deinit
? 這是在釋放引用類型實例時。 為什么會被解除分配? 由於它的引用計數達到0,即引用計數的內存管理是什么。
不知道為什么它的引用計數在另一個任務中達到零。
我不知道您所說的“在另一項任務中”是什么意思。 根據定義,它的引用計數在deinit
為零。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.