Как выпустить MPMoviePlayerController? - PullRequest
26 голосов
/ 30 марта 2009

У меня есть пара просмотров, которые получают доступ к видеоплееру. Я поместил следующий код в метод в 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».

Как мне выпустить плеер?

Ответы [ 6 ]

18 голосов
/ 30 марта 2009

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

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

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

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

7 голосов
/ 16 августа 2009

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

- (void)moviePlayBackDidFinish:(NSNotification *)notification {
    MPMoviePlayerController *theMovie = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self
        name:MPMoviePlayerPlaybackDidFinishNotification
        object:theMovie];
    [theMovie stop];
    [theMovie release];
}
3 голосов
/ 23 апреля 2010

для iphone OS 3.2 тебе нужно позвонить [moviePlayer pause]; перед звонком [moviePlayer stop];

2 голосов
/ 04 февраля 2010

Остановка и отпускание были для меня недостаточны, если игрок не достиг конца.

Мое решение - установить 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]; 
}
0 голосов
/ 10 сентября 2010

Это, казалось, значительно уменьшило память. Однако для 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];    
}
0 голосов
/ 17 февраля 2010

У меня была та же проблема, и я только что понял, что установил метод уведомления с помощью объекта: nil (это была копия вставки).

У меня было несколько уведомлений, хотя вообще не должно было быть никаких уведомлений.

Вот мой новый код установки уведомлений, который исправил все (см. Объект: moviePlayer):

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

Надеюсь, это поможет. Теперь весь мой код работает правильно.

...