Подтвердить что ты не робот

Как освободить MPMoviePlayerController?

У меня есть пара взглядов, которые обращаются к игроку. Я применил следующий код в методе AppDelegate для этих представлений. Они отправляют в файл, чтобы играть. Код работает нормально, но я знаю, что где-то требуется релиз. Если я добавлю последнюю строку в качестве выпуска или автозагрузки, приложение выйдет из строя, как только пользователь нажмет на видеоплеер.

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

Я получаю эту ошибку:

objc [51051]: FREED (id): сообщение videoViewController, отправленное освобожденному объекту = 0x1069b30

Программный сигнал: "EXC_BAD_INSTRUCTION".

Как я могу освободить плеер?

4b9b3361

Ответ 1

Я обнаружил, что MPMoviePlayerController должен быть отправлен сообщение остановки, прежде чем вы сможете безопасно его освободить. Таким образом, я делаю это в handlePlaybackEnd - сначала я останавливаю его, затем я его автоматически проверяю. Вызов выпуска не работает слишком хорошо:

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

Все становится немного сложнее в том, что MPMoviePlayerPlaybackDidFinishNotification может отправляться более одного раза, но вызов stop/autorlease дважды не принесет вам никакой пользы. Поэтому вам нужно как-то защититься от этого.

Наконец, кажется, что требуется несколько итераций основного цикла цикла, пока вы не сможете безопасно создать новый экземпляр MPMoviePlayerController. Если вы сделаете это слишком быстро, вы получите звук, но нет видео. Большое удовольствие, да?

Ответ 2

Чтобы ответить на комментарий FourSpace выше, вы можете удалить наблюдателя уведомлений, чтобы вы не получали его несколько раз:

- (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

У меня была та же проблема, и я просто понял, что я установил метод уведомления с объектом: 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];    
}