iOS8中的AVPlayerItem addobserver问题

您好我正在使用AVPlayer在我的UITableViewCells上播放video,它在iOS 7上工作正常,但在iOS8中它崩溃与以下错误。

'An instance 0x7c01b000 of class AVPlayerItem was deallocated while key value observers were still registered with it. 

这是我的代码

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ......... ......... if(cell.videoPlayer!= nil && cell.videoPlayer.currentItem != nil) { [cell.videoItem removeObserver:self forKeyPath:@"playbackBufferEmpty" context:nil]; [cell.videoItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp" context:nil]; } cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionInitial context:nil]; [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionInitial context:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; cell.avLayer.frame = CGRectMake(5, 9, 310, 310); [cell.contentView.layer addSublayer: cell.avLayer]; [ cell.videoPlayer play]; [cell.contentView addSubview:cell.videoActivity]; return cell; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSArray* cells = homeTabl.visibleCells; for (HomeCell* cell in cells) { if (object == cell.videoItem && [keyPath isEqualToString:@"playbackBufferEmpty"]) { if (cell.videoItem.playbackBufferEmpty) { NSLog(@"buffering"); cell.videoActivity.hidden = NO; } } else if (object == cell.videoItem && [keyPath isEqualToString:@"playbackLikelyToKeepUp"]) { if (cell.videoItem.playbackLikelyToKeepUp) { cell.videoActivity.hidden = YES; [cell.videoPlayer play]; } } } } -(void)scrollViewDidScroll:(UIScrollView *)aScrollView { NSArray* cells = homeTabl.visibleCells; for (HomeCell* cell in cells) { [cell.videoPlayer pause]; [cell.avLayer removeFromSuperlayer]; cell.videoPlayer = nil; cell.videoItem = nil; } 

可能是什么原因 ? 我已经经历了这个问题,但是我不能在我的代码中实现这个。 请帮我解决这个问题。

根据我的经验,删除观察者是iOS中最耀眼的领域之一。 您需要非常仔细地平衡调用AddObserver和RemoveObserver。 我发现一个安全的方法是将任何AddObserver调用放入对象的Init方法,然后在Dealloc方法中使用RemoveObserver调用来平衡这些调用。 在你的情况下,这将在你的'videoItem'子类。 (这个代码没有被选中)

 - (id) initWithOwner:(id)owner { self = [super init]; if( self ) { _owner = owner; [self addObserver:_owner forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionInitial context:nil]; } return self; } - (void) dealloc { [self removeObserver:_owner forKeyPath:@"playbackBufferEmpty" context:nil]; } 

我不知道在哪里声明videoItem,但基本上你创build了一个名为VideoItem的新类,并在其中创build一个名为initWithOwner的新的初始化器: 在你的cellForRowAtIndexPath:方法中,当你创build你的新单元格时,你也创build了一个VideoItem的实例,并作为所有者

 self.videoItem = [[VideoItem alloc] initWithOwner:self]; 

没有更多的代码,我不能更详细地指定这个。 你也可以考虑在xcode中先将代码格式化,然后剪切并粘贴到SO中以保持整洁。