I am getting a memory leak when i click the play button....
I am testing with that "Leak" tool under "Run and performance tool"....on simulator
I am getting that leak when i click the play button first time.....
Here is my code....
-(IBAction)play
{
[self setPlayer];
[self playme];
}
-(IBAction)stop
{
[self stopme];
[self releasePlayer];
}
-(void)setPlayer
{
NSURL *file = [[NSURL alloc] initFileURLWithPath:
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"shut up.mp3"]];
NSError *err = nil;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:&err];
[file release];
player.numberOfLoops = -1;
[player prepareToPlay];
player.volume=1.0;
}
-(void)playme
{
if (!isPlaying)
{
[player play];
isPlaying=YES;
}
}
-(void)stopme
{
if (isPlaying)
{
[player stop];
isPlaying=NO;
}
}
-(void)releasePlayer
{
if(!isPlaying)
{
[player release];
player=nil;
}
isPlaying=NO;
}
I think, the below statement is the source of memory leak,
Here is the SO posts which has discussed the same issue.
AVAudioPlayer memory leak
AVAudioPlayer memory leak
AVAudioPlayer Memory Leak - Media Player Framework
Here is the blog post
AVAudioPlayer Memory Leak
EDITED:
As per the blog tutorial your code must be look like below.
The leak-free version stores the pointer returned by alloc, rather than the pointer returned by initWithData:error:. That way, whatever happens, the player can still be released.
The blog post in Jhaliya's answer describes a leak that's specific to the situation when your player can't init the audio, for example when it can't find the file.
The real problem with your code is that you only release the player if the user explicitly stops the audio. If the audio plays through to the end, you have a player instance with a retainCount of 1. Then if the user hits play again, you create a new player and assign it to the
player
variable, leaking the old one.The easiest solution to this is to make
player
a retained property:Then, instead of assigning to the ivar directly, use the mutator to set the player, which will implicitly release the previously set instance, if there is one:
And don't forget to release it in your dealloc: