Когда аудио завершено, доступ к navigationController приводит к EXC_BAD_ACCESS - PullRequest
1 голос
/ 16 декабря 2011

Происхождение этого вопроса происходит от ответа на этот вопрос .

У меня есть серия головоломок, которые управляются их собственными ViewControllers. Рабочий процесс выглядит следующим образом:

UINavigationViewController -> Контроллер представления меню -> Контроллер маршрутизации -> Случайно выбранный контроллер представления головоломки

«Контроллер вида маршрутизации» случайным образом выбирает контроллер вида головоломки, чтобы поместить его в стек. Как только кто-то решил головоломку, я проигрываю аудио-образец You You, а затем вытаскиваю контроллер представления из стека. В этот момент Routing View Controller случайным образом выбирает следующую головоломку. Вот мой код для воспроизведения звука и для извлечения контроллера вида головоломки из стека:

-(void) playSound:(SystemSoundID)soundID withClientData:(UIViewController*)clientData {
     soundIsPlaying = true;

     if (clientData)
         AudioServicesAddSystemSoundCompletion(soundID, nil, nil, soundFinishedPlaying, (__bridge void *)clientData);
     else
         AudioServicesAddSystemSoundCompletion(soundID, nil, nil, soundFinishedPlaying, nil);

     AudioServicesPlaySystemSound(soundID);
} 

void soundFinishedPlaying(SystemSoundID ssID, void *clientData)
{
    soundIsPlaying = false;

    if(clientData) {
        NSLog(@"clientData not null!");
        UINavigationController * navController = ((__bridge UIViewController *) clientData).navigationController;
        if (navController){
            NSLog(@"navController not null!");
            [navController popViewControllerAnimated:false];
        } else {
            NSLog(@"NavController was nil!");
        }
     } 

}

Проблема в том, что после решения второй головоломки я получаю сообщение об ошибке EXC_BAD_ACCESS в этой строке кода в soundFinishedPlaying:

UINavigationController * navController = ((__bridge UIViewController *) clientData).navigationController;

Если я отлаживаю эту строку кода, я вижу, что clientData имеет ссылку на UINavigationController, поэтому я немного озадачен тем, почему я вижу эту ошибку.

Я подозреваю, что это может быть связано с тем, что мне нужно указать прямую функцию C для soundFinishedPlaying и / или с тем фактом, что мне нужно передать ссылку на UIViewController как пустоту *.

Пожалуйста, дайте мне знать, где я ошибся или есть ли лучший способ инициировать переход просмотра после завершения воспроизведения аудиоклипа. Заранее спасибо!

1 Ответ

1 голос
/ 19 декабря 2011

Я понял, что здесь происходит.Проблема была с приведением «моста», которое я выполнял в этой строке:

AudioServicesAddSystemSoundCompletion(soundID, nil, nil, soundFinishedPlaying, (__bridge void *)clientData);

Если я вместо этого изменил режим моста на __bridge_retained, это гарантировало, что мой экземпляр NavigationController не будет разыменовываться до тех пор, пока не завершится метод завершения звукабыло завершено.Использование __bridge_retained также означает, что я должен явно разыменовать точку, используя CFRelease (...) в soundFinishedPlaying.

Я все еще использую инструмент анализа кода Apple, чтобы подтвердить, что других утечек памяти нет, поэтомуесли я здесь упускаю какие-либо детали, не стесняйтесь их заполнять.

К вашему сведению ... Спасибо этому посту за указание в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...