开发者

AVAudioPlayer memory leaks

开发者 https://www.devze.com 2023-03-05 12:18 出处:网络
I have this method in a开发者_C百科n exterior class that gets called whenever the charachter in my game hits a wall (about once every 5 seconds on average). I dont understand it. I thaught I was on to

I have this method in a开发者_C百科n exterior class that gets called whenever the charachter in my game hits a wall (about once every 5 seconds on average). I dont understand it. I thaught I was on top of the memory management. Everytime the method is called, a small amount of memory is leaked (Malloc 38 or 42 bytes) This keeps happening, and the game freezes up. Here is my code:

-(void)playBoing {
    int x = (arc4random()%3)+1;
    NSString *path = [NSString stringWithFormat:@"/boing_0%i.aif", x];

    NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
    resourcePath = [resourcePath stringByAppendingString:path];

    if (boing != nil) {
        boing = nil;
        boing.delegate = nil;
        [boing release];
    }
    boing = [[AVAudioPlayer alloc] initWithContentsOfURL:
             [NSURL fileURLWithPath:resourcePath] error:nil];

    boing.delegate = self;
    boing.volume = 1;
    [boing play];
}


Of course, it's lead to memory leak

First you said, that boing is nil (but memory is not deallocated, leaked), then trying to send release message to nil. You should do it like this:

[boing release];
boing = [[AVAudioPlayer alloc] initWithContentsOfURL:
             [NSURL fileURLWithPath:resourcePath] error:nil];

No need to check boing for nil before releasing, because sending message to nil do nothing


I think, the below statement is the source of memory leak,

player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:&err];

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

As per the blog tutorial your code must be look like below.

-(void)setPlayer
{

    NSURL *file = [[NSURL alloc] initFileURLWithPath:
                   [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"shut up.mp3"]];
    NSError *err = nil;

    NSData *data = [NSData dataWithContentsOfFile:file];
    AVAudioPlayer *player = [AVAudioPlayer alloc];    
    if([player initWithData:audioData error:NULL])
     {

        player.numberOfLoops = -1;
        [player prepareToPlay];
        player.volume=1.0;
        [player autorelease];
    } 
    else 
    {
        [player release];
        player = nil;
    }
    [file release];
}

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消