removeObserver:forKeyPath:在keyPath通知

时间:2017-02-26 19:22:06

标签: ios nsnotificationcenter

我创建了一个观察者来跟踪我的AVPlayer的“速率”。每次AVPlayer速率按预期变化时,都会显示观察者通知。但是,当我在播放AVPlayer正在播放的项目结束时尝试删除观察者时,我得到以下崩溃:

*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <MediaController 0x10181e000> for the key path "rate" from <NSNotificationCenter 0x1740da080> because it is not registered as an observer.'

这没有意义,因为必须注册观察者才能让我移除观察者。换句话说,我删除观察者的点是在接收观察者通知的处理程序中。很明显,观察员已经注册。这是我创建观察者的相关代码:

 AVPlayerItem *item = [[AVPlayerItem alloc]initWithURL:address];
 moviePlayer = [[AVPlayer alloc]initWithPlayerItem:item];

 [moviePlayer addObserver:self
               forKeyPath:@"rate"
                  options:NSKeyValueObservingOptionNew
                  context:NULL];

然后当正在播放的项目结束时,在收到观察者通知后执行以下处理程序代码:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

if ([keyPath isEqualToString:@"rate"]) {
    float rate = [change[NSKeyValueChangeNewKey] floatValue];
    if (rate == 0.0) {
        // Playback stopped

        if (CMTimeGetSeconds(moviePlayer.currentTime) >=
            CMTimeGetSeconds(moviePlayer.currentItem.duration)) {
            // Playback reached end

            // Remove further notifications until the next time we need the movie player
            [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:@"rate"];

执行removeObserver后,会发生应用程序崩溃。我还尝试添加&amp; moviePlayer的非null上下文并删除具有该上下文的观察者,但它仍然崩溃。我也试过延迟删除,但这也没有解决问题。

为避免此次崩溃,我错过了什么?

1 个答案:

答案 0 :(得分:2)

您没有向NSNotificationCenter注册观察者,但使用moviePlayer对象。

尝试做:

// Remove further notifications until the next time we need the movie player
[moviePlayer removeObserver:self forKeyPath:@"rate"];