So I'm trying to use the CoreAudio method AUGraphAddRenderNotify(...)
but I need a reference to the class that created this notification within the notification block. Because this is a C function, I can't simply add a [weak self] in
closure capture. Looking at the Documentation, the last parameter of this method is allowed to be an UnsafeMutableRawPointer
that will be passed in during the execution of the block as the first parameter. Following this suggestion, here is the code that I have:
let selfPointer = Unmanaged.passUnretained(self).toOpaque()
AUGraphAddRenderNotify(graph, { (audioPlayerPointer, _, _, _, _, _) -> OSStatus in
let audioPlayer = Unmanaged<AudioPlayer>.fromOpaque(audioPlayerPointer).takeUnretainedValue()
...
return noErr
}, selfPointer)
Here is my question:
I need to figure out how I can safely get the value behind this pointer (accounting for nil). More specifically, I want to safely access the audioPlayer and make sure that it hasn't been deallocated by the time I use it. Currently, everything works just fine until the audioPlayer gets deallocated and then my app crashes. I know that I can use AUGraphRemoveRenderNotify(...)
to stop the notification before the object gets deallocated but unfortunately this method is not what I'm looking for. How can I check if the object that the pointer is pointing to has already been deallocated?
Thanks in advance!
Interestingly, weak references don't actually point to the target object that they model. They point to side tables, whose lifetime is different from the target object.
nil
-ed out (which is what you observe as a user), but also deincrements the side-table entrySince these side table entries aren't exposed to "user land" Swift code, you can't make a raw pointer to them, and so you can't really deal with weak references in this way.
I have a few ideas of what you can do instead, though I haven't tried them.
You can exploit UnsafeMutableRawPointer
pointer to pass in a Weak<T>
wrapper, like:
struct Weak<T: AnyObject> {
wear var object: T?
}
Though I think it'll have to be a class
, in this case.