【问题标题】:How to release MPMoviePlayerController?如何释放 MPMoviePlayerController?
【发布时间】:2010-10-16 06:27:54
【问题描述】:

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

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

我收到此错误:

objc[51051]: FREED(id): message videoViewController sent to freed object=0x1069b30

节目接收信号:“EXC_BAD_INSTRUCTION”。

我应该如何释放播放器?

【问题讨论】:

    标签: iphone memory-management mpmovieplayercontroller


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 是的 - 我已经有了声音/没有视频的东西。惊人的!如何防范多个通知?如果处理多个,它会崩溃吗?
    • 你必须有某种标志:如果没有设置,设置它并释放播放器。如果已设置,请不要执行任何操作。
    • 您也可以将 MPMoviePlayerController 作为 ivar 存储在委托中。在moviePlaybackDidFinish: 方法中,您可以释放ivar 并将其设置为nil,而不是访问notification.object。第二个通知会将 stop 和 autorelease 发送到 nil,这很好。
    • 有时在用户点击“完成”按钮后,我仍会在后台收听视频中的音频。自动释放 ivar 播放器(而不是释放)对我有用。
    【解决方案2】:

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

    - (void)moviePlayBackDidFinish:(NSNotification *)notification {
        MPMoviePlayerController *theMovie = [notification object];
        [[NSNotificationCenter defaultCenter] removeObserver:self
            name:MPMoviePlayerPlaybackDidFinishNotification
            object:theMovie];
        [theMovie stop];
        [theMovie release];
    }
    

    【讨论】:

    • 我试过这个,但是我的内存消耗没有下降?这是否意味着内存尚未释放?
    【解决方案3】:

    适用于 iphone os 3.2 你需要打电话 [电影播放器​​暂停]; 打电话之前 [电影播放器​​停止];

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

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

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

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

        【讨论】:

          【解决方案6】:

          这似乎显着减少了内存。但是对于 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];    
          }
          

          【讨论】:

            猜你喜欢
            • 2011-06-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-26
            相关资源
            最近更新 更多