IPhone - CGBitmapContextCreateImage Leak, anyone else with this problem?

Does anyone else have this problem? I change images quite often with NSTimer. After using the tools, it doesn't detect any memory leaks, but my alloc object just keeps growing. It points directly to the CGBitmapContextCreateImage.

Does anyone know of a solution? or even possible ideas?

-(UIImage *) resizedImage:(UIImage *)inImage : (CGRect)thumbRect : (double)interpolationQuality
{
    CGImageRef          imageRef = [inImage CGImage];
    CGImageAlphaInfo    alphaInfo = CGImageGetAlphaInfo(imageRef);

    if (alphaInfo == kCGImageAlphaNone)
        alphaInfo = kCGImageAlphaNoneSkipLast;

    // Build a bitmap context that the size of the thumbRect
    CGContextRef bitmap = CGBitmapContextCreate(
                    NULL,
                    thumbRect.size.width,
                    thumbRect.size.height,      
                    CGImageGetBitsPerComponent(imageRef),
                    4 * thumbRect.size.width,   
                    CGImageGetColorSpace(imageRef),
                    alphaInfo
                    );

    // Draw into the context, this scales the image
    CGContextSetInterpolationQuality(bitmap, interpolationQuality);
    CGContextDrawImage(bitmap, thumbRect, imageRef);

    // Get an image from the context and a UIImage
    CGImageRef  ref = CGBitmapContextCreateImage(bitmap);
    UIImage*    result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);   // ok if NULL
    CGImageRelease(ref);

    return [result autorelease];
}

      

+2


source to share


5 answers


Should you be releasing imageRef?



CGImageRelease(imageRef);

      

+1


source


Just a sanity check: are you freeing the returned UIImage? Normally I would expect a function that allocates a new object (in this case UIImage) to create in the name?

You might want



return [result autorelease]

      

?

0


source


Why not use a simpler one UIGraphicsBeginImageContext

?

@implementation UIImage(ResizeExtension)
- (UIImage *)resizedImageWithSize:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)interpolationQuality;
@end
@implementation UIImage(ResizeExtension)
- (UIImage *)resizedImageWithSize:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)interpolationQuality
{
    UIGraphicsBeginImageContext(newSize);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, interpolationQuality);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

      

@end

Moreover, this returns the image saved by the current autocomplete pool; if you create many of these images in a loop, manually select and delete NSAutoreleasePool

.

0


source


Ok, the problem is that we are defining the return from CGBitmapContextCreateImage to be CGImageRef, it should be CGImage. The reason your allocations (im assuming malloc) keep increasing is because the CGImage itself is never freed. Try the below code. Also, there is no need to automatically evaluate the result as it is never "Alloc'd".

Once the changes are made to the reassigned installations, this time you hopefully won't see a constant increase in bytes in real time.

I typed this on PC so it might get a syntax error if you put it in Xcode; however this should do the trick.

 // Get an image from the context and a UIImage     
CGImage  cgImage = CGBitmapContextCreateImage(bitmap);     
UIImage*    result = [UIImage imageWithCGImage:cgImage];      
CGContextRelease(bitmap);   // ok if NULL     
CGImageRelease(cgImage);      
return result; 

      

0


source


If you are using garbage collection use CFMakeCollectable (posterFrame). If you are using traditional memory management it is very simple:

return (CGImageRef)[(id)posterFrame autorelease];

      

You pass a CFTypeRef (in this case, CGImageRef) to an Objective-C object pointer, send the -autorelease message, and then feed the result back to CGImageRef. This pattern works for almost any type that is compatible with CFRetain () and CFRelease ().

0


source







All Articles