Могу ли я хранить ссылки AVAudioPlayer в NSMutableArray и воспроизводить их по желанию? - PullRequest
2 голосов
/ 19 июня 2010

У меня есть библиотека из 16 коротких аудиоклипов, которые мне нужно играть в быстрой последовательности. Я понял, что создание и подготовка AVAudioPlayer объектов в режиме реального времени было слишком большим вопросом для iPhone.

Итак, вместо этого, во время инициализации моего приложения, я предварительно создаю серию AVAudioPlayers, так что каждый из них в основном предварительно загружен одним из моих 16 звуков, поэтому они готовы для воспроизведения в любое время.

Проблема в том, чтобы сохранить это в чистоте, я хотел бы хранить ссылки для этих 16 AVAudioPlayers в NSMutableArray, чтобы я мог легко получить их, просто зная расположение их массива. Однако, как я это делаю, это сбой симулятора без сообщений об ошибках в журнале:

Вот как я сейчас настраиваю массив ссылок AVAudioPlayer:

// (soundPlayers is an NSMutableArray instance var)
soundPlayers = [NSMutableArray arrayWithCapacity:(NSUInteger)16];                                       

for ( int i = 0; i < 16; i++ ) {
    NSString *soundName = [NSString stringWithFormat:@"sound-%d", i];
    NSString *soundPath = [[NSBundle mainBundle] pathForResource:soundName ofType:@"mp3"];
    NSURL *soundFile = [[NSURL alloc] initFileURLWithPath:soundPath];   
    AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFile error:nil];
    [soundFile release];
    [p prepareToPlay];
    [soundPlayers addObject:(id)p];
    [p release];
}

Затем позже я пытаюсь загрузить, скажем, звук # 8 и воспроизвести его:

// (soundPlayer is an AVAudioPlayer instance var)
self.soundPlayer = [soundPlayers objectAtIndex:(NSUInteger)8];
[soundPlayer play]; 

Есть идеи? Также кто-нибудь знает, будут ли полезны какие-либо изящные средства отладки, которые поставляются с XCode, для решения подобных проблем?

Ответы [ 3 ]

2 голосов
/ 19 июня 2010

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

Попробуйте: soundPlayers = [[NSMutableArray alloc] init]; вместо.

Вероятно, это не является причиной сбоя, но попробуйте NSLogging self.soundPlayer, прежде чем вызывать -play, чтобы убедиться, что это не nil. И еще одна маленькая мелочь: вам не нужно вводить p при добавлении его в массив. Просто позвоните [soundPlayers addObject:p] без (id).

Я не уверен в точной причине вашей аварии, просто просматриваю код и указываю, что не выглядит правильным. Надеюсь, это поможет!

1 голос
/ 19 июня 2010

Скорее всего, в какой-то момент ваш изменяемый массив soundPlayers будет освобожден, поскольку вы его не сохраняете.Я хотел бы убедиться, что ваше свойство для массива установлено так, чтобы оно сохраняло и делало то, что Macatomy ранее указывал:

self.soundPlayers = [[NSMutableArray alloc] init];

Или даже initWithCapacity:

0 голосов
/ 19 июня 2010

Это выглядит нормально для меня, за исключением того, что, возможно, вы не должны вызывать prepareToPlay , прежде чем поместить их в массив.

Вероятно, лучше сделать это, когда вы на самом деле собираетесь их сыграть.Описание этого метода говорит, что он предварительно загружает буферы и получает аудиооборудование для воспроизведения.Делать это 16 раз за один раз может быть слишком много.

РЕДАКТИРОВАТЬ - вам также следует добавить проверку ошибок, отсутствующие результаты, которые могут указывать на что-то неправильное, initWithContentsOfURL: outError: возвращает ошибкусообщение.Воспользуйтесь этим:

NSError* error = nil;
AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFile error:&error];
if (error) {
    NSLog(@"ERROR: %@, URL=%@", error.localizedDescription, soundFile);
}
...