[英]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.