gpt4 book ai didi

ios - iOS8 中的 AVPlayerItem addobserver 问题

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:50:11 29 4
gpt4 key购买 nike

您好,我正在使用 AVPlayer 在我的 UITableViewCells 上播放视频,它在 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;


}

可能是什么原因?我已经完成了这个 SO 问题,但我无法在我的代码中实现它。请帮我解决这个问题。

最佳答案

根据我的经验,删除观察者是 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 在哪里声明,但基本上您创建了一个名为 VideoItem 的新类,并在其中创建了一个名为 initWithOwner: 的新初始化程序。在您的 cellForRowAtIndexPath: 方法中,当您创建新单元格时,您还创建了一个 VideoItem 实例并将自己作为所有者传递

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

如果没有您的更多代码,我无法更详细地说明这一点。您可能还会考虑先在 xcode 中格式化您的代码,然后将其剪切并粘贴到 SO 中以使其更整洁。

关于ios - iOS8 中的 AVPlayerItem addobserver 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27838356/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com