Метод обратного вызова AudioServicesAddSystemSoundCompletion не вызывается после нескольких вызовов - PullRequest
4 голосов
/ 20 июня 2011

Я использую AudioServicesAddSystemSoundCompletion в своем приложении, чтобы определить, когда закончился звук, а затем вызвать другое действие. По какой-то причине я получаю следующее поведение: оно работает для первых 8–12 звуков (это по крайней мере то, что я тестировал), а затем обратный вызов, определенный для AudioServicesAddSystemSoundCompletion, больше не вызывается.

Вот мой код для создания звука:

NSString *soundPath = [[NSBundle mainBundle] pathForResource:[[soundFileName componentsSeparatedByString:@"."]objectAtIndex:0]ofType:@"wav"];
Log2(@"soundFileName: %@", soundFileName);
CFURLRef soundURL = (CFURLRef)[NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(soundURL, &sound);
AudioServicesAddSystemSoundCompletion(sound, nil, nil, playSoundFinished, (void*) self);

для воспроизведения звука:

AudioServicesPlaySystemSound(sound);

и сделать что-нибудь, когда закончится воспроизведение звука:

void playSoundFinished (SystemSoundID sound, void *data) {
    pf //Typedef for PRETTY_FUNCTION log

    AudioServicesRemoveSystemSoundCompletion(sound);
    [AppState sharedInstance].b_touchesFREE = TRUE;

    if([[AppState sharedInstance].ma_cardsToCheck count] >= 2)
{        
        [[AppState sharedInstance].vc_spiel pairFound];
}   

    if (((Card*)data).b_isTurnedFaceUp) {
        [AppState sharedInstance].i_cardsTurnedFaceUp --;
    }

    [(Card*)data release];
}

Кто-нибудь из вас знает, почему он работает несколько раз, а потом перестает работать?

Спасибо заранее. Maverick1st

***** Редактировать ***** Я только что узнал, что это происходит, когда я пытаюсь воспроизвести звук во второй раз. Может быть, я забыл выпустить его где-нибудь? Но я всегда думал, что AudioServicesRemoveSystemSoundCompletion обрабатывает управление памятью.

***** Еще одно редактирование ***** Поэтому размещение этого в Stackoverflow заставило меня задуматься о проблеме немного глубже, и я нашел решение сейчас (по крайней мере, я думаю, что я понял;)). К сожалению, я не могу ответить на вопрос для себя в течение следующих 7,5 часов, поэтому мне нужно отредактировать вопрос.

Только для того, чтобы вы лучше поняли мою проблему.

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

Так что я просто попробовал это без AudioServicesRemoveSystemSoundCompletion, и теперь оно работает.

Единственное, в чем я сейчас не уверен, так это в том, что это может привести к утечке памяти или что-то в этом роде. Но пока все работает нормально.

Если бы кто-то мог сказать мне, если это нормально в отношении использования памяти, я был бы действительно счастлив. :)

С уважением. Maverick1st

1 Ответ

5 голосов
/ 02 сентября 2011

Если вы создаете звук (и устанавливаете завершение звука) только один раз за время существования приложения, все должно быть в порядке с точки зрения управления памятью. Это всегда ты создаешь - ты отпускаешь.

Тем не менее, вы должны позвонить

AudioServicesRemoveSystemSoundCompletion(sound);
AudioServicesDisposeSystemSoundID(sound);

когда вам больше не нужен звук (скорее всего, в методе dealloc объекта, на котором вы создали (или сохраняете ссылку)) звук. Не меняйте порядок этих двух, иначе у вас будет утечка памяти.

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

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