Objective c MPMoviePlayer激活状态错误?

Objective c MPMoviePlayer激活状态错误?,objective-c,ios,Objective C,Ios,我使用内置的MPMoviePlayerController播放视频。使用两个MPMoviePlayerController时遇到问题(请注意,没有两个视频同时播放)。我可以在第一个控制器上播放任意数量的视频,完成后将其丢弃,然后分配另一个MPMoviePlayerController。一旦我在第二个控制器上设置了controlStyle,我就会得到一个带有 由于未捕获异常“NSInternalInconsistencyException”而终止应用程序,原因:“电影播放器的激活状态错误(1) 我

我使用内置的MPMoviePlayerController播放视频。使用两个MPMoviePlayerController时遇到问题(请注意,没有两个视频同时播放)。我可以在第一个控制器上播放任意数量的视频,完成后将其丢弃,然后分配另一个MPMoviePlayerController。一旦我在第二个控制器上设置了controlStyle,我就会得到一个带有

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

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

我还是会撞车。相当令人沮丧

我不明白为什么不可能使用两个控制器,只要它们不是同时播放。我不想为了让视频正常工作而去钻研AVPlayer的东西

谢谢

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

- (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];
}

我想我明白你的问题了。你甚至在分配玩家之前就已经释放了它。基本上,编译器第一次检查代码时,会看到
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
是一个实例变量,因此您实际上要做的是检查它是否已经设置为对象

刚刚解决了我自己的问题。我在视频视图的viewDidUnload方法中为movieplayer提供了release和nil。如果视图从superview中删除,则不会调用此函数,因此我必须在隐藏视频的同时发布一个版本

我仍然有点困惑为什么这个问题会首先发生,因为我使用的是两个单独分配的MPmoviePlayer


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

您应该显示一些代码,以便我们知道您是如何创建和处理电影控制器的。顺便问一下,如果不设置controlStyle呢?您仍然会遇到异常,对吗?遗憾的是,这并没有解决问题:(我真的被这个问题难住了。我希望苹果在设计这个类时能做得更好。我对我在这个类中看到的问题的数量不太感兴趣。另外,我相信在上面的例子中,player=nil和release行都被切换了好吧,所以你的问题是内存管理,这是我的第一点。我没有测试我的代码,只是你可以这么做,但你最终还是去了我指给你看的地方。