26

ムービー プレーヤーにアクセスするビューがいくつかあります。これらのビューの AppDelegate のメソッドに次のコードを入れました。再生するファイル名を送信します。コードは正常に動作しますが、どこかでリリースが必要であることはわかっています。最後の行を release または autorelease として追加すると、ユーザーがムービー プレーヤーで [完了] を押すとアプリがクラッシュします。

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

次のエラーが表示されます。

objc[51051]: FREED(id): 解放された object=0x1069b30 に送信されたメッセージ videoViewController

プログラム受信シグナル: 「EXC_BAD_INSTRUCTION」。

プレーヤーを解放するにはどうすればよいですか?

4

6 に答える 6

18

私が見つけたのは、MPMoviePlayerController を安全に解放する前に、停止メッセージを送信する必要があるということです。だから私は handlePlaybackEnd でそれを行います - 最初に停止し、次に自動解放します。release の呼び出しがうまく機能していないようです。

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

MPMoviePlayerPlaybackDidFinishNotification が複数回送信される可能性があるという点で全体が少し複雑になりますが、stop/autorlase を 2 回呼び出しても何の役にも立ちません。そのため、何らかの方法でそれを防ぐ必要があります。

最後に、新しい 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の場合、[moviePlayerpause]を呼び出す必要があります。[moviePlayerstop]を呼び出す前;

于 2010-04-23T08:45:46.760 に答える
2

プレーヤーが最後まで到達しない場合、停止してリリースするだけでは十分ではありませんでした。

私の解決策は 、リリースする前に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]; 
}
于 2010-02-04T16:35:56.480 に答える
0

私は同じ問題を抱えていましたが、通知メソッドを object:nil に設定していることに気付きました (コピーペーストでした)。

通知がまったくないはずなのに、複数の通知がありました。

すべてを修正した新しい通知セットアップ コードを次に示します (object: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 に答える