繁体   English   中英

在 deinit 中调用 dispatchQueue.sync 会导致 self 的无主引用

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM