【问题标题】:MPMoviePlayer wrong activation state?MPMoviePlayer 激活状态错误?
【发布时间】:2011-10-10 15:32:27
【问题描述】:

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

的 SIGABRT

由于未捕获的异常'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];
}

【问题讨论】:

  • 您应该显示一些代码,以便我们知道您如何准确地创建和处置电影控制器。对了,不设置controlStyle怎么办?你仍然得到例外,对吧?

标签: objective-c ios


【解决方案1】:

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

尝试对您的 ma​​kePlayer 方法进行此更改:

- (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 是一个实例变量,所以你实际上需要做的是检查它是否已经被设置为一个对象。

【讨论】:

  • 可悲的是,这并没有解决问题:(我真的很难过这个问题。我希望苹果在设计这个类方面做得更好。对我遇到的问题数量并不感到兴奋在里面看到。另外,我相信 player = nil 和 release 线在你上面的例子中被切换了
【解决方案2】:

刚刚解决了我自己的问题。我在视频视图的 viewDidUnload 方法中有电影播放器​​的 release 和 nil 。视图从其父视图中删除时不会调用此方法,因此我只需要在隐藏视频的同时释放一个版本。

我仍然对为什么首先会出现这个问题感到有些困惑,因为我使用了两个单独分配的 MPMoviePlayer。

tldr:确保第一个 MPMoviePlayer 已完全释放,然后再尝试分配第二个。

【讨论】:

  • 好的,所以你的问题是内存管理,这是我的第一点。我没有测试我的代码,只有你可以这样做,但你最终去了我指给你的地方。
猜你喜欢
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多