2014-09-22 83 views
0

正如我的對象中聲明的對象:除去觀察者的dealloc與

AVQueuePlayer *queuePlayer; 

在代碼我已經添加的觀察者:

- (void) playStreamedTrack: (Track *) track { 

[queuePlayer addObserver:self forKeyPath:@"status" options:0 context:nil]; 

     [queuePlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC) 
                queue:nil 
              usingBlock:^(CMTime time) { 
               progress = time.value/time.timescale; 
              }]; 
} 

我試圖除去觀察者跟隨,但不工作

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

    [queuePlayer removeObserver:self forKeyPath:@"status" context:nil]; 
} 

我該如何刪除觀察者?

+1

是否調用了'dealloc'? – trojanfoe 2014-09-22 07:09:21

+0

是的,我使用的dealloc方法在上面。 控制檯中的錯誤是: ***由於未捕獲的異常'NSInternalInconsistencyException'而終止應用程序,原因:'類AVQueuePlayer的實例0x7f970b55ae00被解除分配,而鍵值觀察者仍在註冊它。現有的觀測信息:的語境:爲0x0,物業:0x7f970b6fb390> )」 – 2014-09-22 07:39:26

+0

觀察員註冊了多少次?它看起來像是在錯誤的地方註冊,如果這個「軌道」不止一次播放。 – trojanfoe 2014-09-22 07:41:58

回答

2

[AVPlayer addPeriodicTimeObserverForInterval] doc所述,您必須保留返回值以便稍後能夠移除觀察者。

所以,你需要在你的類接口

@property (nonatomic, strong) id playerObserver; 

添加屬性,並存儲返回的值當您創建觀察者

if(self.playerObserver) 
    [queuePlayer removeTimeObserver:self.playerObserver]; 
self.playerObserver = [self.queuePlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC) 
                    queue:nil 
                   usingBlock:^(CMTime time) { 
                    progress = time.value/time.timescale; 
                   }]; 

在dealloc中,你可以再放開觀察者

- (void)dealloc {  
    [queuePlayer removeTimeObserver:self.playerObserver]; 
    [queuePlayer removeObserver:self forKeyPath:@"status" context:nil]; 
} 

請注意,在您的區塊中,您可能需要使用弱r參考您的實例以避免保留週期。如果你的「progress」變量實際上是一個實例變量,你必須使用像這樣的弱引用:

__typeof__(self) __weak weakSelf = self; 

self.playerObserver = [self.queuePlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC) 
                    queue:nil 
                   usingBlock:^(CMTime time) { 
                    weakSelf.progress = time.value/time.timescale; 
                   }]; 
+0

完成但仍然:***因未捕獲異常'NSInternalInconsistencyException'而終止應用程序,原因:'類AVQueuePlayer的實例0x7fac9d0b0ba0被釋放,而鍵值觀察者仍在其中註冊。當前觀察信息:上下文:0x0,屬性:0x7fac9eddda30> – 2014-09-22 08:50:48

+0

我已經編輯我的答案,刪除以前的觀察員,然後再添加一個新的(如果有的話)。這可能是爲什麼你仍然有一個註冊觀察員。 – Phil 2014-09-22 09:25:53

+0

菲爾非常感謝,現在很奇怪它顯示: ***終止應用程序由於未捕獲的異常'NSInvalidArgumentException',原因:'AVPlayer的一個實例無法刪除由不同的AVPlayer實例添加的時間觀察者'。 – 2014-09-22 09:47:10