26

我有几个访问电影播放器​​的视图。对于这些视图,我已将以下代码放入 AppDelegate 的方法中。他们发送文件名进行播放。该代码工作正常,但我知道某处需要发布。如果我将最后一行添加为释放或自动释放,一旦用户在电影播放器​​上按下完成,应用程序就会崩溃。

MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] 
                 initWithContentURL:[NSURL fileURLWithPath:moviePath]];
moviePlayer.movieControlMode = MPMovieControlModeDefault;
[moviePlayer play];
//[moviePlayer release];

我收到此错误:

objc[51051]: FREED(id): message videoViewController发送到释放对象=0x1069b30

节目接收信号:“EXC_BAD_INSTRUCTION”。

我应该如何释放播放器?

4

6 回答 6

18

我发现必须先向 MPMoviePlayerController 发送停止消息,然后才能安全地释放它。所以我在 handlePlaybackEnd 中执行它——首先我停止它,然后我自动释放它。调用 release 似乎不太好用:

- (void) moviePlayBackDidFinish : (NSNotification *) notification
{
  VideoPlayerController * player = notification.object;
  [player stop];
  [player autorelease];
}

整个事情变得有点棘手,因为 MPMoviePlayerPlaybackDidFinishNotification 可以被多次发送,但是两次调用 stop/autolease 对你也没有任何好处。所以你需要以某种方式防范这种情况。

最后,在您可以安全地创建新的 MPMoviePlayerController 实例之前,似乎需要对主运行循环进行几次迭代。如果你做得太快,你会得到声音但没有视频。很好玩吧?

于 2009-03-29T23:09:11.563 回答
7

要回答 4thSpace 对上述答案的评论,您可以删除通知观察者,这样您就不会多次收到它:

- (void)moviePlayBackDidFinish:(NSNotification *)notification {
    MPMoviePlayerController *theMovie = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self
        name:MPMoviePlayerPlaybackDidFinishNotification
        object:theMovie];
    [theMovie stop];
    [theMovie release];
}
于 2009-08-15T22:47:23.283 回答
3

对于 iphone os 3.2,您需要调用 [moviePlayer pause];在调用 [moviePlayer stop] 之前;

于 2010-04-23T08:45:46.760 回答
2

如果玩家没有到达终点,停止和释放对我来说是不够的。

我的解决方案是在发布之前将其设置 moviePlayer.initialPlaybackTime = -1moviePlayBackDidFinish:

-(void)playMovie: (NSString *)urlString{ 
    movieURL = [NSURL URLWithString:urlString]; 
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; 
    moviePlayer.initialPlaybackTime = 0; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish: ) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer] ;

    moviePlayer.scalingMode = MPMovieScalingModeAspectFit; 
    moviePlayer.movieControlMode = MPMovieControlModeDefault;
    moviePlayer.backgroundColor = [UIColor blackColor];

    [moviePlayer play];
}

-(void)moviePlayBackDidFinish: (NSNotification*)notification{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer] ; 

    moviePlayer.initialPlaybackTime = -1; 

    [moviePlayer stop]; 
    [moviePlayer release]; 
}
于 2010-02-04T16:35:56.480 回答
0

我遇到了同样的问题,我刚刚意识到我用 object:nil 设置了通知方法(这是一个复制粘贴)。

尽管我根本不应该收到任何通知,但我收到了多个通知。

这是我修复所有的新通知设置代码(请参阅对象:moviePlayer):

[[NSNotificationCenter defaultCenter] addObserver:self 
                           selector:@selector(moviePlaybackDidFinish:) 
                           name:MPMoviePlayerPlaybackDidFinishNotification 
                           object:moviePlayer]; 

希望有帮助。现在我所有的代码都可以正常工作。

于 2010-02-17T12:40:05.077 回答
0

这似乎显着减少了内存。但是对于 IOS 4.1 来说似乎还不错。

- (void)videoFinishedCallback:(NSNotification *)aNotification
{
    thePlayer = [aNotification object];
    [[NSNotificationCenter defaultCenter]
    removeObserver:self
    name:MPMoviePlayerPlaybackDidFinishNotification object:thePlayer];

    thePlayer.initialPlaybackTime = -1;

    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
        [thePlayer pause]; 
    #endif

    [thePlayer stop];
    [thePlayer release];    
}
于 2010-09-10T16:42:29.450 回答