How to find the leaky faucet that loads into Malloc 32kb
I have been messing around with Leaks trying to find which function is not being deallocated (I am still new to this) and could real开发者_高级运维ly use some experienced insight.
I have this bit of code that seems to be the culprit. Every time I press the button that calls this code, 32kb of memory is additionally allocated to memory and when the button is released that memory does not get deallocated.
What I found was that everytime that AVAudioPlayer
is called to play an m4a file, the final function to parse the m4a file is MP4BoxParser::Initialize()
and this in turn allocates 32kb of memory through Cached_DataSource::ReadBytes
My question is, how do I go about deallocating that after it is finished so that it doesn't keep allocating 32kb every time the button is pressed?
Any help you could provide is greatly appreciated!
- (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];
}
The trick to memory management in Cocoa is to balance out any calls to alloc
, retain
or copy
with a subsequent call to release
.
In this case, you are sending alloc
to initialize your theAudio
variable, but you are never sending release
.
Assuming that you will only have one sound playing at a time, the best way to do this is with a property on your controller (the one that has this -touchesBegan
method). The property declaration would look like this:
@property (nonatomic, retain) AVAudioPlayer * theAudio;
You will then need to set theAudio
to nil
in your init
method:
theAudio = nil; // note: simple assignment is preferable in init
And be sure to release the variable in your dealloc
method:
[theAudio release];
Now, your touchesBegan
could look like this:
- (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
}
This line looks culprit to me:
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
When does this resource get released?
精彩评论