wL_
wL_

Reputation: 1007

NSNotificationCenter removing wrong observers?

Is there any corner case behaviors for removeObserver:name:object:? In the following block of code, my observer isn't being registered properly:

- (void)setPlayerItem:(AVPlayerItem *)playerItem {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd:)
                                                 name:nil
                                               object:playerItem];

    [playerItem addObserver:self
                 forKeyPath:kStatus
                    options:0
                    context:(__bridge void*)self];

    [playerItem addObserver:self
                 forKeyPath:kPlaybackBufferEmpty
                    options:0
                    context:(__bridge void*)self]; // For adding a buffering activity indicator

    id temp = playerItem_;
    playerItem_ = [playerItem retain];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
    [temp removeObserver:self forKeyPath:kPlaybackBufferEmpty];
    [temp removeObserver:self forKeyPath:kStatus];
    [temp release];
}

However, if I change the order around to:

- (void)setPlayerItem:(AVPlayerItem *)playerItem {    
    [playerItem addObserver:self
                 forKeyPath:kStatus
                    options:0
                    context:(__bridge void*)self];

    [playerItem addObserver:self
                 forKeyPath:kPlaybackBufferEmpty
                    options:0
                    context:(__bridge void*)self]; // For adding a buffering activity indicator

    id temp = playerItem_;
    playerItem_ = [playerItem retain];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];
    [temp removeObserver:self forKeyPath:kPlaybackBufferEmpty];
    [temp removeObserver:self forKeyPath:kStatus];
    [temp release];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd:)
                                                 name:nil
                                               object:playerItem];
}

All the notifications post just fine. This leads me to believe something strange is happening when I call:

    [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp];

Am I missing something really obvious here? I'm on iOS 6 with no ARC.

Upvotes: 0

Views: 472

Answers (3)

wL_
wL_

Reputation: 1007

Found the answer. Turns out it has to do with passing in nil for the observer name. Calling [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp]; will remove self from observing any notifications posted by temp. However, in the corner case that temp is nil, this line of code will remove self as an observer all together.

Upvotes: 1

user1078170
user1078170

Reputation:

@Lee is correct that the name should not be nil but it also should not be the name of the observer. Rather it should be the name of the notification that you are registering to observe. e.g., UIDeviceOrientationDidChangeNotification. Add the name of the notification that you want to observe in that param and also pass it as the name param when you remove observer

Upvotes: 0

Lee
Lee

Reputation: 31

Name shouldn't be nil. Did you try giving your observer a name?

Upvotes: 0

Related Questions