My program has a memory leak

2020-04-01 08:13发布

-(IBAction)play2;

{
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =CFBundleCopyResourceURL(mainBundle, 
                                             (CFStringRef) @"Bear3", CFSTR ("wav"), NULL);

    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}

This is giving me an error:

potential leak of an object allocated " CFBundleResourceURL
returns a Core Foundation object with a +1 retain count

5条回答
冷血范
2楼-- · 2020-04-01 08:31

CFBundleCopyResourceURL creates a CFURLRef object that you own, so you need to relinquish ownership of this object at some point with CFRelease. Similarly you will need to balance your call to AudioServicesCreateSystemSoundID with another call to AudioServicesDisposeSystemSoundID.

For Core Foundation, functions that have the word Create or Copy in their name return an object that you own, so you must relinquish ownership of it when you are done with it. For more information about Core Foundation memory management, see the Core Foundation Memory Management Programming Guide.

Just to give you a hint, I would probably handle the memory management like this (although I haven't coded Objective-C for a while). This also assumes you want to keep the URL reference for whatever reason:

@interface MyClass
{
    CFURLRef soundFileURLRef;
    UInt32 soundID;
}

@end

@implementation MyClass

- (id) init
{
    self = [super init];
    if (!self) return nil;

    CFBundleRef mainBundle = CFBundleGetMainBundle();

    soundFileURLRef = CFBundleCopyResourceURL(mainBundle, CFSTR("Bear3"), CFSTR("wav"));

    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);

    return self;
}

- (void) dealloc
{
    AudioServicesDisposeSystemSoundID(soundID);
    CFRelease(soundFileURLRef);
    [super dealloc];
}

- (IBAction) play2
{
    AudioServicesPlaySystemSound(soundID);
}
查看更多
做自己的国王
3楼-- · 2020-04-01 08:33

AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID); - leak here, because create added to retain count

use AudioServicesDisposeSystemSoundID after playing sound

查看更多
Summer. ? 凉城
4楼-- · 2020-04-01 08:35

CFBundleCopyResourceURL contains copy so your retain count on soundFileURLRef is in fact 1. When you are done with it call CFRelease(soundFileURLRef) to decrement your retain count.

In addition to the error you're getting, SAKrisT's answer about calling AudioServicesDisposeSystemSoundID on the object you created with AudioServicesCreateSystemSoundID is also something to address.

查看更多
家丑人穷心不美
5楼-- · 2020-04-01 08:37

If you're not using ARC (available in xcode 4.2) then you need to release anything you alloc. add [alert release] after [alert show].

查看更多
可以哭但决不认输i
6楼-- · 2020-04-01 08:46

Whenever you use the keyword 'alloc' , it means you are allocating some memory space for your object. Now if you don't release it yourself or autorelease it, then it shows 'memory leak'. It is not only about uialertview, but for every other objects also.
You may want to release the alertview object in dealloc() method, but still it will show memory leak as the memory is unused for a long time.
So , first you show the alert by [alert show], then you need the object anymore, so release it by [alert release];
Enjoy !! :)

查看更多
登录 后发表回答