[英]Calling dispatchQueue.sync in deinit causes unowned reference of self
In a class, I put all members read/write in a serial dispatchQueue to protect multi-thread access.在一个类中,我将所有成员读/写在串行 dispatchQueue 中以保护多线程访问。 But I got a fatal error of unowned reference to self
when I pass [unowned self]
to dispatchQueue's task in deinit.但是当我在 deinit 中将 [unowned [unowned self]
传递给 dispatchQueue 的任务时,我遇到了对self
的 unowned 引用的致命错误。
In the following example, I can still read self
and refCount(self)
is still not 0 in deinit{}
before calling self.q.sync{...}
.在下面的示例中,在调用self.q.sync{...}
之前,我仍然可以读取self
并且refCount(self)
在deinit{}
仍然不是 0。 Then fatal error raised immediately when passing [unowned self]
to queue's task然后在将[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
Is the class.deinit{}
a special scope where we should not pass self
to another thread or task? class.deinit{}
是一个特殊的范围,我们不应该将self
传递给另一个线程或任务吗?
I also try to pass using [weak self]
, and the self
is still a nil
.我也尝试使用[weak self]
传递,而self
仍然是nil
。 Don't know why its reference count reached zero at another task.不知道为什么它的引用计数在另一个任务中达到零。
What is deinit
?什么是去deinit
? It is when a reference type instance is being deallocated.这是在释放引用类型实例时。 Why is it being deallocated?为什么会被解除分配? Because its reference count reached 0. That is what reference count memory management is .由于它的引用计数达到0,即引用计数的内存管理是什么。
Don't know why its reference count reached zero at another task.不知道为什么它的引用计数在另一个任务中达到零。
I don't know what you mean by "at another task".我不知道您所说的“在另一项任务中”是什么意思。 Its reference count is zero in deinit
by definition.根据定义,它的引用计数在deinit
为零。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.