MPMoviePlayer错误的激活状态?

时间:2011-07-21 22:30:53

标签: objective-c ios

我正在使用内置的MPMoviePlayerController来播放视频。我在使用两个MPMoviePlayerControllers时遇到了问题(请注意,在同一时间没有播放两个视频)。我可以在第一个控制器上播放尽可能多的视频,在完成后处理它,然后分配另一个MPMoviePlayerController。一旦我在第二个控制器上设置了controlStyle,我就会得到一个带有

的SIGABRT

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'电影播放器​​的激活状态错误(1)

我在网上搜索过,在堆栈溢出时发现了类似的问题。那家伙说他忘了删除播放完成的通知。我相信我已经使用[[NSNotificationCenter defaultCenter] removeObserver:self]正确完成了这一步;

我仍然得到了崩溃。相当令人沮丧!

我不明白为什么只要它们没有同时播放就不可能使用两个控制器。我宁愿不必深入研究AVPlayer的内容,只是为了让视频正常工作。

谢谢!

编辑:注释掉controlStyle分配仍然会导致崩溃。下面是已发布的callstack,以及该类中的一些重要方法。

- (void) makePlayer;
{
[player.view removeFromSuperview];
[player release];
player = [MPMoviePlayerController new];
player.view.frame = self.bounds;
player.view.hidden = YES;
player.controlStyle = MPMovieControlStyleNone;
player.scalingMode = MPMovieScalingModeNone;
[self addSubview: player.view];
}

- (void) dealloc;
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
[player.view removeFromSuperview];
[player release];
[super dealloc];
}

- (void) setMovieByName: (NSString *) name;
{
[self makePlayer];
player.shouldAutoplay = NO;
[player setContentURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource: name ofType: @"mov"]]];
[player stop];
[player prepareToPlay];
[[NSNotificationCenter defaultCenter] removeObserver: self];
[[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(movieDimensionsKnown:) name:MPMovieNaturalSizeAvailableNotification object: player];
[[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(playbackStateChanged:) name:MPMoviePlayerPlaybackStateDidChangeNotification object: player];
[[NSNotificationCenter defaultCenter] addObserver: self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object: player];
}

- (void) playbackFinished: (NSNotification *) n
{   
player.view.hidden = YES;
if ([delegate respondsToSelector: @selector(moviePlayerImageViewPlaybackDidFinish:)])
    [delegate moviePlayerImageViewPlaybackDidFinish: self];
}

2 个答案:

答案 0 :(得分:0)

我想我看到了你的问题。在分配之前,您将发布player。基本上,第一次编译器通过你的代码时,它会看到player得到保留计数-1(因为release调用),然后在分配时再次上升到0(因为new电话)。因此,当您第一次尝试设置任何属性时,没有对象将属性设置为(player永远不会有保留计数为1)。 你应该做的是检查player是否存在,只有它已经存在,然后你才能释放它。

尝试对 makePlayer 方法进行此更改:

- (void) makePlayer {

if (player != nil) {

[player.view removeFromSuperview];
player = nil;
[player release];

}

player = [MPMoviePlayerController new];
player.view.frame = self.bounds;
player.view.hidden = YES;
player.controlStyle = MPMovieControlStyleNone;
player.scalingMode = MPMovieScalingModeNone;
[self addSubview: player.view];
}

编辑:稍作修改。 player是一个实例变量,因此您实际需要做的是检查它是否已经设置为对象。

答案 1 :(得分:0)

刚刚解决了我自己的问题。我在视频视图的viewDidUnload方法中为电影播放器​​发布了nil和nil。视图被从超级视图中删除后不会被调用,因此我只是在隐藏视频的同时抛出一个版本。

我仍然有点混淆为什么问题首先发生,因为我使用了两个单独分配的MPMoviePlayers。

tldr:确保在尝试分配第二个MPMoviePlayer之前完全释放了第一个MPMoviePlayer。