removeObserver:forKeyPath:在 keyPath 通知期间崩溃
removeObserver:forKeyPath: crashes during keyPath notification
我创建了一个观察器来跟踪我的 AVPlayer 的 "rate"。每次 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 后,应用崩溃。我还尝试添加 &moviePlayer 的非空上下文并删除具有该上下文的观察者,但它仍然崩溃。我也试过延迟删除,但这也没有解决问题。
我缺少什么来避免这次崩溃?
您没有使用 NSNotificationCenter 注册观察者,而是使用 moviePlayer
对象。
尝试做:
// Remove further notifications until the next time we need the movie player
[moviePlayer removeObserver:self forKeyPath:@"rate"];
我创建了一个观察器来跟踪我的 AVPlayer 的 "rate"。每次 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 后,应用崩溃。我还尝试添加 &moviePlayer 的非空上下文并删除具有该上下文的观察者,但它仍然崩溃。我也试过延迟删除,但这也没有解决问题。
我缺少什么来避免这次崩溃?
您没有使用 NSNotificationCenter 注册观察者,而是使用 moviePlayer
对象。
尝试做:
// Remove further notifications until the next time we need the movie player
[moviePlayer removeObserver:self forKeyPath:@"rate"];