Search code examples
iosnsnotificationcenteraddobserver

object in addObserver is different


I'm have the following code:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreen:)
                                             name:MPMoviePlayerWillEnterFullscreenNotification
                                           object:nil];

And the method uses a property of self:

- (void)moviePlayerWillEnterFullscreen:(NSNotification *)notification
{
    NSLog(@"%@", self.videoItem._id);
}

Sometimes (not always) the self object inside the handler is a different object (and an uninitialized one which causes a crash)

I can't seem to figure out what am I doing wrong, and how to avoid this case. Is the "self" object gets copied?


Solution

  • Echoing @0x7fffffff's comment, if you register an observation, you almost always want to have:

    - (void)dealloc {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    

    There is (usually) little cost to removing yourself from the notification center, and it does not care if you are an observer or not, so this is good insurance that I recommend for any object that ever observes an notification.

    (Removing yourself as an observer is O(n) in the total number of registered observations in the center. So if you have thousands of notification observations, then removeObserver: can take nontrivial time, but so will postNotification:. In this case, you generally should reduce how many observations you make rather than avoid using removeObserver:.)

    Following up on your comment, you almost never want to use addObserver: in viewDidLoad. You almost always want to do it in viewDidAppear: and remove yourself as an observer in viewWillDisappear: (or viewWillAppear:/viewDidDisappear:, whichever is convenient), and also in dealloc as a safety. It is almost always incorrect to be observing notifications in a view controller that is not currently onscreen.