iOS 5中AVPlayerItem的实例已被释放

6
当我尝试从我的iPhone(位于documentsDirectory中)播放视频时,我在使用iOS 5时遇到了以下错误,而在iOS 4.3上运行良好:
一个AVPlayerItem类的实例0x168da0在键值观察者仍然注册它时被释放了。观察信息已经泄漏,甚至可能被错误地附加到其他对象上。在调试器中设置NSKVODeallocateBreak断点以停止此处。以下是当前的观察信息: ( Context: 0x0, Property: 0x10b570> Context: 0x0, Property: 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];
3个回答

13

编辑: 在我发布下面的答案后,我注意到每当控制器被重新分配时,错误就会出现,即使我完全没有设置通知处理程序。由于故障来自于MP框架内部的代码,我想这似乎是一个操作系统的错误。

我在使用ARC的基于Storyboard的iOS 5项目中遇到了同样的问题。问题是使用栈上的临时变量引用电影控制器 - 在我的情况下,我假设与ARC交互,但它可能更为基本。无论如何,似乎某些东西过早释放/丢失(例如发生播放错误时),并且日志填充了您描述的输出类型。

在拥有类中定义属性存储电影控制器引用解决了我的问题; 即:

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

@@implementation MyClass
@synthesize movieController = _movieController;

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

self.movieController = [...];
如果您正在使用合成存取器来访问属性,那么无论您是使用手动引用计数还是自动引用计数,生成的设置方法都应正确释放旧的电影控制器(如果有)以设置新的电影控制器。作为脚注,如果您在MPMoviePlayerPlaybackDidFinishNotification通知处理程序中手动dealloc/'unreference'(将其设置为nil),则可能会注意到错误回来了。所以不要这样做:-)

5
这是一个老问题,但以防万一其他人也遇到同样的问题,MPMoviePlayerController似乎不喜欢某些NSURL,即使它们被视为有效对象。 "秘密"是将文件路径作为NSString获取,然后使用“[NSURL fileURLWithPath:URLStringPath]”来创建您用于创建MPMoviePlayerController实例的URL。 - Rog
你为我节省了无数的时间。非常棒的研究工作。我都快抓狂了。 - SteveB

0
啊。您正在从SomethingElse对象观察TekkPoint对象,而SomethingElse对象是添加和删除观察者的对象,对吗?(这是正常的操作方式;我只是想澄清一下。)
看起来您的TekkPoint对象在SomethingElse仍在观察它时被释放了。SomethingElse的dealloc方法没有被调用,因为被释放的是TekkPoint而不是SomethingElse。
如果您计划观察一个可能在观察者消失之前就消失的对象,则需要一种通知观察者应该删除其观察者的方法。您的TekkPoint可以有一个alive属性,也会被SomethingElse观察,当设置为NO时,观察TekkPoint的所有人都会将自己作为观察者删除。

-5

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

放置

[[NSNotificationCenter defaultCenter] removeObserver:self];

willWillDisappeardealloc


2
NSNotificationCenter和KVO不同,你混淆了两种完全不同的技术。 - steipete
1
他在询问MPMoviePlayerPlaybackDidFinishNotification,这不是KVO。 - Kent Nguyen
您的意思是 willWillDisappear 吗?是指 viewWillDisappear 吗? :) - Sabobin
上面的问题回答错误,请仔细阅读问题。 - codercat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接