0

removeObserver:name:object: の特殊な動作はありますか? 次のコード ブロックでは、オブザーバーが正しく登録されていません。

- (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];
}

ただし、順序を次のように変更すると:

- (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];
}

すべての通知は問題なく投稿されます。これにより、次のように呼び出したときに何か奇妙なことが起こっていると思われます。

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

ここで本当に明らかな何かが欠けていますか?私はARCなしでiOS 6を使用しています。

4

3 に答える 3

1

答えが見つかりました。nilオブザーバー名を渡すことと関係があることがわかりました。呼び出しは、によって投稿された通知の監視から[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:temp]; 削除されます。ただし、tempがのコーナーケースでは、このコード行はオブザーバーとしてまとめて削除されます。selftempnilself

于 2012-10-16T04:31:34.547 に答える
0

名前は nil であってはなりません。オブザーバーに名前を付けてみましたか?

于 2012-10-10T01:56:35.293 に答える
0

@Leeは、名前がnilであってはならないことは正しいですが、オブザーバーの名前であってはなりません。むしろ、監視するために登録している通知の名前にする必要があります。例: UIDeviceOrientationDidChangeNotification。そのパラメーターで観察したい通知の名前を追加し、オブザーバーを削除するときに名前パラメーターとして渡します

于 2012-10-10T03:03:49.907 に答える