2017-02-26 109 views
1

我創建了一個觀察者來跟蹤我的AVPlayer的「速率」。每當AVPlayer速率如預期發生變化時,就會顯示觀察者通知。然而,當我嘗試在播放上,該AVPlayer播放該項目結束時刪除觀察者,我得到以下崩潰:removeObserver:forKeyPath:keyPath通知期間崩潰

*** 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的執行,發生應用程序崩潰。我也嘗試添加moviePlayer的非空上下文並使用該上下文刪除觀察者,但仍然崩潰。我也嘗試延遲刪除,但這也不能解決問題。

我錯過了什麼來避免這次崩潰?

回答

2

您沒有向NSNotificationCenter註冊觀察者,但註冊了moviePlayer對象。

嘗試做:

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