In the OS X v10.11 beta release notes, I find the following:
NSNotificationCenter and NSDistributedNotificationCenter no longer send notifications to registered observers that may be deallocated. If the observer is able to be stored as a zeroing-weak reference the underlying storage stores the observer as a zeroing weak reference. Alternatively, if the object cannot be stored weakly (because it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) the object is stored as a non-weak zeroing reference. This means that observers are not required to un-register in their deallocation method. [emphasis mine]
This doesn't make sense to me. If it is a non-weak reference, wouldn't it be a strong reference, then? So the NSNotificationCenter would still be an owner, so the object wouldn't deallocate (until manually unregistered), so it's nonsensical in this context to say it's "zeroing".
If this is referring to a sort of __unsafe_unretained
reference, then the question is…how then would NSNotificationCenter avoid messaging a zombie?
The answer for this lies deep within the objective-c runtime, and how
__weak
variables actually work. To explain, let's look a little bit atobjc_weak.mm
:As you can see, when custom
-retain
and-release
methods are used by an object, it's not guaranteed that they support weak references at all (also note that you can use an entirely different object for an object's weak references, though that's a topic for another time).This is because weak references are cleaned up by
objc_destructInstance
, which callsobjc_clearDeallocating
, which callsweak_clear_no_lock
.Now,
objc_destructInstance
is NOT required to be called by custom object implementations, although most objects will call it.Thus, the runtime allows you to implement the method
-allowsWeakReference
(andretainWeakReference
) to disable weak references to your object, in which case it's most likely zero'd out by swizzling-dealloc
on the object. Of course, this is all implementation details, so NSNotificationCenter could have it's own innovative way of doing things, but that's my best guess without attempting to disassemble NSNotificationCenter.