Search code examples
iosobjective-cios8nsnotificationcenter

How dealloc method gets called if an object is an observer and registered at notification centre?


Consider a scenario when an object register to Notification center (assume ios 8) so center creates a strong reference to the object. Since <= ios8 center makes strong reference to the object hence retain count increases to one. Now,Apple doc says that we need to remove observer in dealloc() to prevent crash. I didn't get two things here:

  1. How object dealloc() method will get called if center still retaining it? My understanding is unless retain count is zero dealloc() will not get called on this object.
  2. Let's assume dealloc happens and we didn't remove observer. Since object is already deallocated why it is crashing?

Solution

  • The documentation for addObserver contains the following note:

    If your app targets iOS 9.0 and later or macOS 10.11 and later, you don't need to unregister an observer in its deallocation method. If your app targets earlier releases, be sure to invoke removeObserver:name:object: before observer or any object specified in addObserver:selector:name:object: is deallocated.

    This implies that in iOS 8, the observer is held as an unsafe_unretained reference. If the observer is deallocated without removing the observer then a subsequent attempted delivery of the notification will result in an exception since the reference will be to a deallocated object.

    In iOS 9 and later, the observer is held as a weak reference, with NotificationCenter checking the reference for nil before attempting to notify the observer. If you target iOS 9 or later then you do not need to explicitly remove the observer.

    Neither an unsafe_unretained reference nor a weak reference increase the retain count, so registering with NotificationCenter will not prevent the observer from being deallocated.