Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Leak with ARC

+(void)setup {
    UIImage* spriteSheet = [UIImage imageNamed:@"mySpriteSheet.png"];
    CGRect rect;
    animation = [NSMutableArray arrayWithCapacity:numberOfFramesInSpriteSheet];
    int frameCount = 0;

    for (int row = 0; row < numberFrameRowsInSpriteSheet; row++) {
        for (int col = 0; col < numberFrameColsInSpriteSheet; col++) {
            frameCount++;
            if (frameCount <= numberOfFramesInSpriteSheet) {
                rect = CGRectMake(col*frameHeight, row*frameWidth, frameHeight, frameWidth);
                [animation addObject:[UIImage imageWithCGImage:CGImageCreateWithImageInRect(spriteSheet.CGImage, rect)] ];
            }
         }
    }
}

Compiled the above code with ARC enabled. The Analyze tool reports a possible memory leak since imageWithCGImage:: returns UIImage with count +1, then reference is lost. Leaks Instrument reports no memory leaks at all. Whats going on here?

Furthermore, since ARC prohibits use of manually using release ect, how does one fix the leak?

Thanks to anyone who can offer any advice.

like image 887
Z.O. Avatar asked Sep 22 '12 01:09

Z.O.


People also ask

How do I find out what is causing my memory leak?

To find a memory leak, look at how much RAM the system is using. The Resource Monitor in Windows can be used to accomplish this. In Windows 8.1 and Windows 10: To open the Run dialogue, press Windows+R, then type "resmon" and click OK.

Can memory leaks be fixed?

In most cases, you can fix the Windows 10 memory leak issues yourself. You can close resource-intensive apps, disable certain startup apps, and perform similar tasks to fix a memory leak.

Is memory leak a serious problem?

Memory leaks may not be serious or even detectable by normal means. In modern operating systems, normal memory used by an application is released when the application terminates. This means that a memory leak in a program that only runs for a short time may not be noticed and is rarely serious.


2 Answers

ARC does not manage C-types, of which CGImage may be considered. You must release the ref manually when you are finished with CGImageRelease(image);

+(void)setup {
    UIImage* spriteSheet = [UIImage imageNamed:@"mySpriteSheet.png"];
    CGRect rect;
    animation = [NSMutableArray arrayWithCapacity:numberOfFramesInSpriteSheet];
    int frameCount = 0;

    for (int row = 0; row < numberFrameRowsInSpriteSheet; row++) {
        for (int col = 0; col < numberFrameColsInSpriteSheet; col++) {
            frameCount++;
            if (frameCount <= numberOfFramesInSpriteSheet) {
                rect = CGRectMake(col*frameHeight, row*frameWidth, frameHeight, frameWidth);
                //store our image ref so we can release it later
                //The create rule says that any C-interface method with "create" in it's name 
                //returns a +1 foundation object, which we must release manually.
                CGImageRef image = CGImageCreateWithImageInRect(spriteSheet.CGImage, rect)
                //Create a UIImage from our ref.  It is now owned by UIImage, so we may discard it.
                [animation addObject:[UIImage imageWithCGImage:image]];
                //Discard the ref.  
                CGImageRelease(image);
            }
         }
    }
}
like image 60
CodaFi Avatar answered Sep 19 '22 13:09

CodaFi


None of the core foundation data structure is dealt with ARC. Many a times this creates a problem. In these case we have to manually release the memory.

like image 42
Anoop Vaidya Avatar answered Sep 22 '22 13:09

Anoop Vaidya