Я бездельничал с Утечками, пытающимися найти, какая функция не освобождается (я все еще плохо знаком с этим), и мог действительно использовать некоторое опытное понимание.
У меня есть этот бит кода, который, кажется, преступник. Каждый раз я нажимаю кнопку, которая называет этот код, 32 КБ памяти дополнительно выделяется памяти и когда кнопка освобождена, что память не становится освобожденной.
То, что я нашел, было этим каждый раз это AVAudioPlayer
назван для проигрывания m4a файла, заключительная функция для парсинга m4a файла MP4BoxParser::Initialize()
и это в свою очередь выделяет 32 КБ памяти через Cached_DataSource::ReadBytes
Мой вопрос, как я иду об освобождении, что после того, как это закончено так, чтобы это не продолжало выделять 32 КБ каждый раз, кнопка нажимается?
Любая справка, которую Вы могли обеспечить, значительно ценится!
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//stop playing
theAudio.stop;
// cancel any pending handleSingleTap messages
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(handleSingleTap) object:nil];
UITouch* touch = [[event allTouches] anyObject];
NSString* filename = [g_AppsList objectAtIndex: [touch view].tag];
NSString *path = [[NSBundle mainBundle] pathForResource: filename ofType:@"m4a"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio prepareToPlay];
[theAudio setNumberOfLoops:-1];
[theAudio setVolume: g_Volume];
[theAudio play];
}
Уловка управления памятью в Какао состоит в том, чтобы сбалансировать любые вызовы alloc
, keep
или ] copy
с последующим вызовом release
.
В этом случае вы отправляете alloc
для инициализации переменной theAudio
, но никогда не отправляете релиз
.
Предполагая, что у вас будет воспроизводиться только один звук, лучший способ сделать это - использовать свойство на вашем контроллере (тот, который имеет этот метод -touchesBegan
).Объявление свойства будет выглядеть так:
@property (nonatomic, retain) AVAudioPlayer * theAudio;
Затем вам нужно будет установить theAudio
на nil
в вашем методе init
:
theAudio = nil; // note: simple assignment is preferable in init
И обязательно освободите переменную в вашем методе dealloc
:
[theAudio release];
Теперь ваш touchesBegan
может выглядеть так:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//stop playing
theAudio.stop;
...
AVAudioPlayer * newAudio = [[AVAudioPlayer alloc] initWithContentsOfUrl:...];
self.theAudio = newAudio; // it is automatically retained here...
theAudio.delegate = self;
[theAudio prepareToPlay];
[theAudio setNumberOfLoops:-1];
[theAudio setVolume: g_Volume];
[theAudio play];
[newAudio release]; // ...so you can safely release it here
}
Эта строка кажется мне виноватой :
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
Когда будет выпущен этот ресурс?