2014-09-22 79 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