Search code examples
cocoa-touchnsnotificationcenter

Why do I need to remove a notification observer before the object I'm observing is deallocated?


From https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html:

You must invoke removeObserver: or removeObserver:name:object: before any object specified by addObserverForName:object:queue:usingBlock: is deallocated

Why does it matter that I stop observing before the object whose notifications I'm observing is deallocated? I understand why I as the observer need to stop observing if I'm going to disappear and the block depends on my existence, but I don't understand why the lifetime of the observed object matters. Am I misinterpreting this?


Solution

  • I understand why I as the observer need to stop observing if I'm going to disappear and the block depends on my existence, but I don't understand why the lifetime of the observed object matters.

    I think that a possible explanation is the following.

    addObserverForName:object:queue:usingBlock description says:

    Adds an entry to the receiver’s dispatch table with a notification queue and a block to add to the queue, and optional criteria: notification name and sender.

    "sender" in this context is just another name for the object parameter, which is described in the following terms:

    The object whose notifications you want to add the block to the operation queue. If you pass nil, the notification center doesn’t use a notification’s sender to decide whether to add the block to the operation queue.

    So, object acts as a sort of filter: when a notification comes in, the notification center decides based on that value (if present) if the block must be added to the specified operation queue.

    Now, consider this:

    1. the observed object is deallocated without the observer to be removed;

    2. a different object, also able to post notifications is created, and it happens it has the same address as the object deallocated at point 1;

    3. now the observer will react to notifications posted by the second object.

    I admit it is a pretty rare case, but it might happen, so you better code against it.