Jason
Jason

Reputation: 634

Why is there a "potential leak"?

Xcode's analyser is complaining that there is a "potential leak of an object". The first line within the following method is highlighted:

- (void)retrieveBeginRestoreData {
    self.restoreContext = [self.image newARGBBitmapContext];
    if (!self.restoreContext) self.restoreData = nil;
    CGRect rect = {{0,0},self.image.size};

    CGContextDrawImage(self.restoreContext, rect, self.image.CGImage);
    self.restoreData = CGBitmapContextGetData(self.restoreContext);
}

I have a property declared as such:

@property (nonatomic, assign) CGContextRef restoreContext

The newARGBBitmapContext is defined by the following:

- (CGContextRef)newARGBBitmapContext {
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    size_t             bitmapByteCount;
    size_t             bitmapBytesPerRow;

    // Get image width, height. We'll use the entire image.
    size_t pixelsWide = CGImageGetWidth(self.CGImage);
    size_t pixelsHigh = CGImageGetHeight(self.CGImage);

    // Declare the number of bytes per row. Each pixel in the bitmap in this
    // example is represented by 4 bytes; 8 bits each of red, green, blue, and
    // alpha.
    bitmapBytesPerRow   = (pixelsWide * 4);
    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

    // Use the generic RGB color space.
    //    colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    colorSpace = CGColorSpaceCreateDeviceRGB();
    if (colorSpace == NULL)
    {
        fprintf(stderr, "Error allocating color space\n");
        return NULL;
    }

    // Allocate memory for image data. This is the destination in memory
    // where any drawing to the bitmap context will be rendered.
    bitmapData = malloc( bitmapByteCount );
    if (bitmapData == NULL)
    {
        fprintf (stderr, "Memory not allocated!");
        CGColorSpaceRelease( colorSpace );
        return NULL;
    }

    // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
    // per component. Regardless of what the source image format is
    // (CMYK, Grayscale, and so on) it will be converted over to the format
    // specified here by CGBitmapContextCreate.
    context = CGBitmapContextCreate (bitmapData,
                                     pixelsWide,
                                     pixelsHigh,
                                     8,      // bits per component
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
    if (context == NULL)
    {
        free (bitmapData);
        fprintf (stderr, "Context not created!");
    }

    // Make sure and release colorspace before returning
    CGColorSpaceRelease( colorSpace );

    return context;
}

I managed to resolve this issue by instead declaring restoreContext as an instance variable in the header file; the "potential leak" warning goes away.

Questions:

Upvotes: 2

Views: 213

Answers (1)

Amin Negm-Awad
Amin Negm-Awad

Reputation: 16650

This line

self.restoreContext = [self.image newARGBBitmapContext];

does the following:

  1. It (potentially) creates an instance object of CGContext.

  2. Since the method name starts with new, an ownership transfer is applied. That means that the receiver (your code) is responsible for releasing it.

When the line of code is run a second time, the reference of the already existing instance of CGContext is overridden without releasing the instance, it points to. The older instance will leak.

Upvotes: 1

Related Questions