2

Мне нужна помощь в решении проблемы, когда я испытываю случайный крах EXC_BAD_ACCESS, который возникает в AudioToolBox (AVAudioSessionPropertyListener) во время перехода между MPMoviePlayerController и MPMusicPlayerController. Ниже показана трассировка вызова:Как я могу решить EXC_BAD_ACCESS, который возникает в AudioToolBox IOS

OS Version:  iPhone OS 5.1 (9B176) 
Report Version: 104 

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x00000009 
Crashed Thread: 0 

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3676ef78 objc_msgSend + 16 
1 AVFoundation     0x31e60b1c _ZL30AVAudioSessionPropertyListenerPvmmPKv + 236 
2 AudioToolbox     0x3630b300 AudioSessionPropertyListeners::CallPropertyListenersImp(unsigned long, unsigned long, void const*) + 268 
3 AudioToolbox     0x3630b5de AudioSessionPropertyListeners::CallPropertyListeners(unsigned long, unsigned long, void const*) + 234 
4 AudioToolbox     0x3630925a SSServer_AudioSessionInterruptionListenerMessage + 50 
5 AudioToolbox     0x362b0d2c _XAudioSessionInterruptionListenerMessage + 56 
6 AudioToolbox     0x36245cdc mshMIGPerform + 368 
7 CoreFoundation     0x3532151c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32 
8 CoreFoundation     0x353214be __CFRunLoopDoSource1 + 134 
9 CoreFoundation     0x3532030c __CFRunLoopRun + 1364 
10 CoreFoundation     0x352a349e CFRunLoopRunSpecific + 294 
11 CoreFoundation     0x352a3366 CFRunLoopRunInMode + 98 
12 GraphicsServices    0x3659f432 GSEventRunModal + 130 
13 UIKit       0x32399e76 UIApplicationMain + 1074 
14 MyGreatApp      0x00054986 main (main.m:14) 
15 MyGreatApp      0x00054944 start + 32 

Мое приложение чередует использование музыкального проигрывателя и проигрывателя. Кинопроигрыватель используется для воспроизведения подкастов. Кинопроигрыватель выделяется с авторекламой каждый раз, когда воспроизводится новый подкаст. Когда я закончил с проигрывателем, я удаляю всех наблюдателей, которые я установил, убедитесь, что проигрыватель фильмов остановлен, и перезапустите музыкальный проигрыватель.

Вот некоторые соответствующий код для инициализации использования видеоплеера:

[musicPlayer pause]; 

self.moviePlayer = [[[MPMoviePlayerController alloc] initWithContentURL: address] autorelease]; // Release the old moviePlayer and create a new one. 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePreloadDidFinish:) name:MPMoviePlayerLoadStateDidChangeNotification object:self.moviePlayer];  

// Register to receive a notification when the movie has finished playing. 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer]; 

// Register to receive a notification when the movie playback state changes (specifically looking for the state of interrupted). 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackStateChanged:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer]; 

[self.moviePlayer play]; 

Фильм может либо закончить после того, как он играет, или пользователь может завершить фильм, нажав кнопку быстрого вперед. Вот соответствующий код для обработки этих двух сценариев:

-(IBAction) fastForwardMovie: (id) sender { 

     // The self.moviePlayer is still playing, but the user wants to skip the rest of the movie/podcast. 
     // Lets fake a movie playback did finish event 
     NSNotification *notification = [NSNotification notificationWithName:MPMoviePlayerPlaybackDidFinishNotification object:nil]; 
     [self moviePlayBackDidFinish: notification]; // Fake a finished playback so that the music player can be restarted 
     return; 
} 


// Notification called when the movie FINISHED playing. 
- (void) moviePlayBackDidFinish:(NSNotification*)notification { 
    // Remove further notifications until the next time we need the movie player 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:self.moviePlayer] ; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer] ; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer] ; 


    // Get rid of the movie player 
    self.moviePlayer.initialPlaybackTime = -1; // seems that the best way to kill the movie player is first setting the playback time to -1 
    [self.moviePlayer stop];     // followed by stopping the player 

    [musicPlayer play]; 
} 

После фильма (подкастов) заканчивает, музыка будет играть даже тогда, когда происходит сбой (но приложение завершается). Это связано с тем, что я пользуюсь музыкальным плеером iPod, но это может означать, что проблема связана с проигрывателем видео.

Последнее примечание. Я попытался тщательно следовать рекомендациям Руководства по программированию аудиозаписей Apple, в котором говорится, что когда желаемая конфигурация должна иметь весь аудиомикс, вы должны «Настроить аудио-сессию с использованием смешанной конфигурации категорий» и «Использовать фильм использование игрока по умолчаниюApplicationAudioSession значение YES ".

Может ли кто-нибудь помочь мне разобраться, что я могу делать неправильно, что приводит к сбою AVAudioSessionPropertyListener с EXC_BAD_ACCESS? Или, по крайней мере, вы можете дать мне предложение о том, как изолировать эту проблему, чтобы определить основную причину?

+0

ii также получаю эти сбои случайно в моем приложении Lucid Reality Check. ii есть очень похожие настройки видео/звука и очень похожий отчет о сбоях, приветствия – kitschmaster

+0

Я также столкнулся с этим сбоем в своем приложении. на самом деле он занимает первое место во всех авариях. Но я понятия не имею. FYI: до сих пор скорость составляет около 790 из 100000 пользователей (новая версия приложения выпущена на 20 дней). – LetBulletFlies

ответ

1

Попробуйте позвонить по телефону [musicPlayer performSelectorOnMainThread:@selector(play) ...]?

+0

Спасибо за это предложение. В настоящее время я тестирую вашу идею. Поскольку это не часто наблюдаемая проблема, мне может потребоваться месяц, чтобы подтвердить это предложение.Если проблема не появится снова, я отмечу это как соответствующий ответ. Между тем, я заметил, что ваше предложение не имеет никаких негативных последствий. Все идет нормально. Спасибо – JeffB6688

+0

Я только что наблюдал этот отчет о сбое снова с предлагаемым изменением. К сожалению, предложенное изменение не устранило проблему. – JeffB6688

0

Мы только что отслеживали очень похожий сбой.

Ours оказываются, как описано здесь:

https://github.com/mattgallagher/AudioStreamer/issues/6

В частности, MyAudioSessionInterruptionListener (или имя обратного вызова передается AudioSessionInitialize), и это inClientData не может быть изменен после того, как он был зарегистрирован, поэтому обратный вызов всегда должен делать что-то разумное, даже если базовый объект был освобожден.

Решение, предлагаемое для AudioStream, заключается в использовании статической переменной и убедитесь, что оно указывает на объект, который в настоящее время интересуется обратным вызовом, и никогда не указывает на освобожденный объект - важно не использовать inClientData.