AVAudioPlayer не выгружает кэшированную память после каждого нового выделения - PullRequest
1 голос
/ 03 мая 2010

Я вижу в Instruments, что когда я воспроизводю звук с помощью стандартного метода-примера «AddMusic», который предоставляет Apple, он выделяет 32 КБ памяти с помощью вызова prepareToPlay (который ссылается на функцию Cache_DataSource::ReadBytes * * * *) * * * * каждый раз, когда назначается новый игрок (то есть каждый раз, когда воспроизводится другой звук). Однако эти кэшированные данные никогда не публикуются.

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

Кто-нибудь из вас сталкивался с этим или что я не так делаю в своем коде? У меня была эта проблема некоторое время, и это действительно беспокоит меня, так как мой код дословно того, что Apple (я думаю).

Как я вызываю функцию:

- (void)playOnce:(NSString *)aSound {

// Gets the file system path to the sound to play.
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:aSound ofType:@"caf"];  

// Converts the sound's file path to an NSURL object
NSURL *soundURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
self.soundFileURL = soundURL;
[soundURL release];

AVAudioPlayer * newAudio=[[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error:nil];  
self.theAudio = newAudio; // automatically retain audio and dealloc old file if new m4a file is loaded

[newAudio release]; // release the audio safely

// this is where the prior cached data never gets released
[theAudio prepareToPlay];

// set it up and play
[theAudio setNumberOfLoops:0];
[theAudio setVolume: volumeLevel];
[theAudio setDelegate: self];
[theAudio play];

}

и затем theAudio освобождается, конечно, методом dealloc.

1 Ответ

2 голосов
/ 05 мая 2010

ответ из другого источника с именем smasher:

Вам нужен отдельный проигрыватель для каждого звука с AVAudioPlayer; Там нет выбора. И единственный способ освободить память из плеера - правильно освободить его после завершения воспроизведения. Просто нажав «Стоп», игрок остается в живых, чтобы вы могли воспроизвести его снова, и не освобождает память.

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

Вы, вероятно, должны отпустить проигрыватель, когда он прекращает воспроизведение, или когда вы выбираете новый звук, или перед созданием проигрывателя для нового звука.

...