iOS 5 AVPlayerItem 的一个实例被释放

Posted

技术标签:

【中文标题】iOS 5 AVPlayerItem 的一个实例被释放【英文标题】:iOS 5 an instance of AVPlayerItem was deallocated 【发布时间】:2011-11-07 10:56:27 【问题描述】:

当我尝试从我的 iPhone(位于文档目录中)播放视频时,我在使用 ios 5 时收到以下错误,而它在 iOS 4.3 上运行良好:

类 AVPlayerItem 的实例 0x168da0 已被释放,而键值观察者仍向其注册。观察信息被泄露,甚至可能被错误地附加到其他对象上。在 NSKVODeallocateBreak 上设置断点以在调试器中停止。这是当前的观察信息: ( 上下文:0x0,属性:0x10b570> 上下文:0x0,属性:0x117ab0>

这里是代码摘录:

MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:[appDelegate.mediaManager loadVideo:[element valueForAttributeNamed:@"value"]]];  

        //create a NSNotificationCenter which call moviePlaybackComplete function when video playback finished
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlaybackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerController];  

        //display the moviePlayer view
        [self.view addSubview:moviePlayerController.view];
        moviePlayerController.fullscreen = YES;  
        [moviePlayerController play];

【问题讨论】:

【参考方案1】:

编辑在下面发布答案后,我注意到每当控制器被重新分配时,错误就会回来,因为旧控制器会自动释放,即使我设置了绝对没有通知本人处理。由于故障来自 MP 框架内的代码,我会说这似乎是一个操作系统错误。

我在使用 ARC 的基于故事板的 iOS 5 项目中遇到了同样的问题。问题是使用堆栈上的临时变量来引用电影控制器 - 在我的情况下,我假设与 ARC 交互,但它可能比这更基本。在任何情况下,看起来好像某些东西过早地被释放/丢失(例如,当发生播放错误时)并且日志被您描述的那种输出填满。

在我的情况下,将电影控制器引用存储在所属类中定义的属性中解决了这个问题;即:

@interface MyClass
@property ( strong, nonatomic ) MPMoviePlayerViewController * movieController;
@end

@@implementation MyClass
@synthesize movieController = _movieController;

// ...then later, this:
//
// MPMoviePlayerController *moviePlayerController = [...];
//
// ...becomes:

self.movieController = [...];

如果您对属性使用合成访问器,那么无论您是使用手动还是自动引用计数,生成的 setter 方法都应该在设置新的之前正确释放旧的电影控制器(如果有的话)。

作为脚注,如果您(比如说)在MPMoviePlayerPlaybackDidFinishNotification 通知处理程序中手动处理该属性(例如)dealloc/'unreference'(设置为nil),那么您可能会注意到错误又回来了。所以不要那样做:-)

【讨论】:

这是一个老歌,但以防万一有人遇到同样的问题,MPMoviePlayerController 似乎不喜欢某些 NSURL,即使它们被视为有效对象。 “秘密”是将文件路径获取为 NSString,然后使用 [NSURL fileURLWithPath:URLStringPath] 创建用于创建 MPMoviePlayerController 实例的 URL。 您为我节省了无数时间。伟大的工作研究。我正在拔头发。【参考方案2】:

啊。您正在从 SomethingElse 对象观察 TekkPoint 对象,而 SomethingElse 对象是添加和删除观察者的对象,对吗? (这是正常的处理方式;我只是想澄清一下。)

看起来您的 TekkPoint 对象正在被释放,而正在观察它的 SomethingElse 对象仍在附近。未调用 SomethingElse 的 dealloc 方法,因为正在释放的是 TekkPoint,而不是 SomethingElse。

如果您计划观察可能在观察者消失之前消失的对象,那么您需要某种方式通知观察者他们应该移除观察者。您的 TekkPoint 可能有一个 alive 属性,SomethingElse 也会观察到该属性,当它设置为 NO 时,观察 TekkPoint 的每个人都会将自己移除为观察者。

【讨论】:

【参考方案3】:

我之前也遇到过同样的错误,当视图消失时只需移除观察者即可清除泄漏。

[[NSNotificationCenter defaultCenter] removeObserver:self];

willWillDisappeardealloc

【讨论】:

NSNotificationCenter != KVO。您正在混合两种完全不同的技术。 他在问MPMoviePlayerPlaybackDidFinishNotification 这不是 KVO 会消失吗?你的意思是 viewWillDisappear 吗? :) 以上问题的答案错误。请仔细阅读问题

以上是关于iOS 5 AVPlayerItem 的一个实例被释放的主要内容,如果未能解决你的问题,请参考以下文章

iOS:收到“304 Not Modified”响应时 AVPlayerItem 中的错误

如何从 AVPlayerItem 创建波形可视化器? (iOS)

iOS 7中的iOS 7 AVPlayer AVPlayerItem持续时间不正确

通过 AvPlayerItem 和 AvPlayer 流式传输时监控下载的字节数 - iOS

带有 tvOS 构建目标的 Objective C 中的 AVPlayerItem.externalMetaData

IOS AVPlayer 无法播放视频