David
David

Reputation:

iPhone programming: avaudioplayer leaks memory on play

I'm new to using avadioplayer and I seems to have a memory when ever I play a sound. I cannot figure out what I am missing to get rid of it inside Instrument. could this be a false positive?

ViewController.h :

@interface ISpectatorViewController : UIViewController <UIAccelerometerDelegate>{

AVAudioPlayer *massCheerSoundID;

}

@property(nonatomic,retain) AVAudioPlayer * massCheerSoundID;

// ViewController.m

- (void)viewDidLoad {

    NSString * filePath;

    filePath = [[NSBundle mainBundle] pathForResource:@"massCheer" ofType:@"mp3"];

    massCheerSoundID = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath ]error:nil];

}

- (void) playSound
{

        if(massCheerSoundID.playing == false)
    {

        massCheerSoundID.currentTime = 0.0;


                //leak here
        [massCheerSoundID play];
    }
}

- (void)dealloc {

    [super dealloc];
    [massCheerSoundID release];

}

I found out what the problem is.

I for got to add the AVAudioPlayerDelegate on the interface since I've set the UIAccelerometerDelegate instead

@interface iSpectatorViewController: UIViewController<AVAudioPlayerDelegate>

and set the

massCheerSoundId.delegate = self

Upvotes: 2

Views: 3145

Answers (5)

user633465
user633465

Reputation: 11

Found the same leak today. Adding MediaPlayer.framework seems to fix that.

That worked for me also. Strange.

Upvotes: 1

shw
shw

Reputation: 614

Found the same leak today. Adding MediaPlayer.framework seems to fix that.

Upvotes: 2

ahmet emrah
ahmet emrah

Reputation: 1858

Try adding MediaPlayer.framework to your project, with no code changes

Upvotes: 3

pgb
pgb

Reputation: 25001

Could it be your dealloc method?

I think the convention is to first release and then call [super dealloc].

I always assumed this was meant to "first release your stuff, then have your parent class handle it".

Your dealloc method should read:

- (void)dealloc {

    [massCheerSoundID release];
    [super dealloc];

}

Upvotes: 1

Daniel
Daniel

Reputation: 22395

Problem might be that you are reinitating the massCheerSoundId over and over if you arent r eleasing your view. So, if you are adding your subview, viewDidLoad gets called and you initialize your player, then perhaps you are removing the subview and adding it again, since you didnt release the view (assuming you have only one copy) dealloc does not get called (i dont think so anyway ), then if you re add the view massCheerSoundId will get overriden and leak.., another problem might be that since you have massCheerSoundId as a property, you allocate it and the setter generated also retains it, so then you are left with a +2 reference count when it should only be +1...so assuming my assumptions are correct i would suggest to write viewDidLoad like this

    - (void)viewDidLoad {    
    NSString * filePath;   
     filePath = [[NSBundle mainBundle] pathForResource:@"massCheer" ofType:@"mp3"]; 
    if(massCharSoundId!=nil)
{
       AVAudioPlayer *p= [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURLfileURLWithPath:filePath ]error:nil];}
       massCheerSoundID = p;
     [p release];
}

Upvotes: 0

Related Questions