Как найти протекающий кран, который загружается в Malloc 32kb - PullRequest
5 голосов
/ 14 апреля 2010

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

У меня есть этот фрагмент кода, который кажется виновником. Каждый раз, когда я нажимаю кнопку, которая вызывает этот код, 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];
}

Ответы [ 2 ]

2 голосов
/ 14 апреля 2010

Хитрость управления памятью в Какао состоит в том, чтобы сбалансировать любые вызовы на alloc, retain или copy с последующим вызовом на release.

В этом случае вы отправляете alloc для инициализации переменной theAudio, но вы никогда не отправляете release.

При условии, что вы будете воспроизводить только один звук за раз, лучший способ сделать это - использовать свойство на вашем контроллере (то, которое имеет этот метод -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
}
1 голос
/ 14 апреля 2010

Мне кажется, эта строка виновна:

theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];  

Когда этот ресурс выйдет?

...