簡體   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