views:

1127

answers:

4

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
A: 

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];
}
Daniel
Is this right? Don't you need: self.massCheerSoundID = p; instead? Otherwise, who's calling retain on massCheerID?
mahboudz
Also, you are loading a sound if massCharSound is NOT nil?
mahboudz
Ur first coment is correct
Daniel
A: 

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];

}
pgb
+1  A: 

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

ahmet emrah
+1  A: 

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

shw