Утечка памяти в AVAudioPlayer - PullRequest
       21

Утечка памяти в AVAudioPlayer

6 голосов
/ 30 августа 2009

Я застрял в какой-то странной проблеме утечки памяти, связанной с AVAudioPlayer, и мне нужна помощь после того, как я попробовал все, что пришло в голову.

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

В этот момент времени (сразу после того, как я позвонил новому игроку - [Воспроизведение игрока]), я получил утечку памяти (размером 3,5 КБ).

Я попробовал следующее:

  • Остановите старого игрока и затем отпустите его - без эффекта

  • Отпустить проигрыватель сразу после инструкции по воспроизведению - воспроизведение не началось

  • Отпустите дважды старого игрока - сбой

  • Утечка памяти НЕ происходит, когда я создаю и играю первым игроком!

Кроме того, в справочнике говорится, что «игра» асинхронна, и поэтому, вероятно, она увеличивает количество ссылок на 1, но в этом случае почему [Player stop] не помогло?

Спасибо

Вот некоторые части кода о том, как я его использую:

- (void) loadAndActivateAudioFunction {
NSBundle        *mainBundle = [NSBundle mainBundle];
NSError         *error;
NSURL           *audioURL = [NSURL fileURLWithPath:[mainBundle pathForResource: Name ofType: Type]];
AVAudioPlayer   *player = [(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];

if (!player) {
    DebugLog(@"Audio Load Error: no Player: %@", [error localizedDescription]);
    DuringAudioPrep = false;
    return;
}
[self lock];
[self setAudioPlayer: player];
[self ActivateAudioFunction];
[self unlock];

}

- (void) setAudioPlayer : (AVAudioPlayer *) player {
if (Player)
{
    if ([Player isPlaying] || Repeat)  // The indication was off???
        [Player stop];
    [Player release];
}
Player = player;

}

- (void) ActivateAudioFunction {
[Player setVolume: Volume];
[Player setNumberOfLoops: Repeat];    
[Player play];

DuringAudioPrep = false;

}

Ответы [ 4 ]

7 голосов
/ 19 ноября 2009

Вот метод для создания AVAudioPlayer без утечек памяти. См. Эту страницу для объяснения .

Я подтвердил в своем приложении, что это устранило утечки моего AVAudioPlayer на 100%.

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path {
    NSData *audioData = [NSData dataWithContentsOfFile:path];
    AVAudioPlayer *player = [AVAudioPlayer alloc];
    if([player initWithData:audioData error:NULL]) {
        [player autorelease];
    } else {
        [player release];
        player = nil;
    }
    return player;
}
2 голосов
/ 01 июля 2011

Реализация протокола AVAudioPlayerDelegate и его метода audioPlayerDidFinishPlaying: успешно: затем освободить объект аудиопроигрывателя

например.

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [player release]; // releases the player object
}
0 голосов
/ 25 ноября 2009

Попробуйте добавить MediaPlayer.framework в ваш проект

0 голосов
/ 30 августа 2009

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

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

    // new players will always be created autoreleased.
    AVAudioPlayer   *player = [[(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error] autorelease];

- (void) setAudioPlayer : (AVAudioPlayer *) player 
{
  if (Player)
  {
      if ([Player isPlaying] || Repeat)  // The indication was off???
            [Player stop];
        [Player release];
  }
  Player = [player retain];
}

Таким образом, вы сохраняете объекты «игрок» только тогда, когда они действительно входят в ваш метод setAudioPlayer, что может упростить отслеживание.

Также убедитесь, что это действительно объект AVAudioPlayer, который протекает. Инструменты должны быть в состоянии проверить это для вас.

...