Question

I am getting a static analyzer warning about some CGImageRef objects. The warning is "Incorrect decrement of the reference count of an object that is not owned at this point by the caller." However, I want it to be owned by the caller. Is there some special wording I need to insert into my Obj-C method? When I make a C function to do literally line for line the exact same thing, the warning disappears. The reason I separate them is because sometimes my app uses the CGImage (for editing), and sometimes it uses a UIImage (for setting a UIImageView).

Here is the relevant code (stripped down to its relevant essentials):

+ (UIImage *)imageFromCompressedData:(NSData *)compressedData withSize:(CGSize)size
{    
    CGImageRef cgImage = [SO2CompressionHandler cgImageFromCompressedData:compressedData withSize:size];
    UIImage *returnImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);

    return returnImage;
}

+ (CGImageRef)cgImageFromCompressedData:(NSData *)compressedData withSize:(CGSize)size
{
    //...decompress data

    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)decodedData);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef outImageRef = CGImageCreate(width, height, 8, 32, 4*width, colorSpace, kCGImageAlphaPremultipliedLast, provider, NULL, false, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);

    if(CGSizeEqualToSize(CGSizeZero, size) || CGSizeEqualToSize(CGSizeMake(width, height), size))
    {
        CGColorSpaceRelease(colorSpace);
        return outImageRef; //Flagged as potential leak
    }

    //...or resize and return the in a similar way
}

It doesn't make sense to release the CGImage before I return it right? Then it would just be invalid memory. So is this a hint that I should be using C-functions? Or does the static analyzer simply not check C-functions. I changed cgImageFromCompressedData:withSize: into CGImageCreateWithCompressedData(NSData *compressedData, CGSize size) and like magic, no more warnings. Should I just ignore the warnings, or do they have some merit? Do I have to add the word "new" or "alloc" to my Obj-C method name to make them go away?

Was it helpful?

Solution

If your method returns a +1 object, its name should start with 'new', e.g. newCGImageFromCompressedData:withSize:. This will tell the analyzer that you are deliberately returning a retained object and passing ownership to the caller.

Alternatively, you can make use of the clang attribute CF_RETURNS_RETAINED by putting this in your method declaration (i.e. in your .h file):

+(CGImageRef)cgImageFromCompressedData:(NSData *)compressedData
                              withSize:(CGSize)size CF_RETURNS_RETAINED;

This also tells the analyzer that the method is supposed to returned a retained object, but without having to change the method selector.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top