简体   繁体   中英

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. But I got a fatal error of unowned reference to self when I pass [unowned self] to dispatchQueue's task in deinit.

In the following example, I can still read self and refCount(self) is still not 0 in deinit{} before calling self.q.sync{...} . Then fatal error raised immediately when passing [unowned self] to queue's task

Example

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()
}

Output

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?

I also try to pass using [weak self] , and the self is still a nil . Don't know why its reference count reached zero at another task.

What is 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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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