Skip Navigation

Ramblings from the team at zinc Roe

Metal Fish Eggs

AVAudioPlayer Memory Leak

While coding the sound for Arctic Shuffle 2, I ran into a non-obvious memory (to me, anyway) memory leak related to the AVAudioPlayer that took forever to track down.

Here was my original code, which leaks if an error occurs in the initWithData:error: method:

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path {
    NSData *data = [NSData dataWithContentsOfFile:path];
    return [[[AVAudioPlayer alloc] initWithData:audioData error:NULL] autorelease];
}

If an error occurs in the initWithData:error: method (say because the file is missing), it returns nil. If it returns nil, autorelease gets called on nil, not on the AVAudioPlayer object, and the AVAudioPlayer object gets leaked.

Here’s the leak-free version:

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path {
    NSData *data = [NSData dataWithContentsOfFile:path];
    AVAudioPlayer *player = [AVAudioPlayer alloc];
    if([player initWithData:audioData error:NULL]) {
        [player autorelease];
    } else {
        [player release];
        player = nil;
    }
    return player;
}

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.

4 comments on AVAudioPlayer Memory Leak
  1. PJ Cabrera Says:

    Thanks for this, you saved me and countless others a bunch of time!

  2. shiva Says:

    Hi Luke can u post full application. When i use ur function
    audioPlayerWithContentsOfFile:(NSString *)path no leak. But i am unable to hear any sound. I commented [player release] and [player autorelease]. Then i am able to hear sound but same memory leak.

    Could you please solve my problem.

    Thanks
    shiva

  3. Luke Says:

    @shiva: You just need to retain the AVAudioPlayer object returned by audioPlayerWithContentsOfFile:

    AVAudioPlayer *player = [someObject audioPlayerWithContentsOfFile:@"someFile.caf"];
    [player retain];

    And then release it when you’re done with it :-)

  4. shiva Says:

    Still i am getting leak.

    I am using more than one sound file.
    When even new image scrolls onto view, i am playing different sound

    Could you please help me?

    Thanks
    shiva

Your Comment…

You can use these tags: <a> <blockquote> <strong> <em> <strike> <code> <pre> Use <pre lang="LANGUAGE"> for syntax highlighted code blocks.