iPhone - CGBitmapContextCreateImage泄漏,有这个问题的其他人?

时间:2009-09-16 07:53:07

标签: iphone memory memory-leaks uiimage cgbitmapcontextcreate

还有其他人遇到过这个问题吗?我经常使用NSTimer重新调整图像大小。使用仪器后,它没有显示任何内存泄漏,但我的objectalloc只是继续攀升。它直接指向CGBitmapContextCreateImage。

有人知道解决方案吗?甚至可能的想法?

-(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's 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];
}

5 个答案:

答案 0 :(得分:1)

你应该发布imageRef吗?

CGImageRelease(imageRef);

答案 1 :(得分:0)

只是一个健全性检查:你是否发布了返回UIImage - 通常我会期望一个分配新对象(在本例中为UIImage)的函数在名称中创建?

也许你想要

return [result autorelease]

答案 2 :(得分:0)

为什么不使用更简单的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

此外,这将返回当前自动释放池保留的图像;如果您在循环中创建了许多这些图像,请手动分配和排空NSAutoreleasePool

答案 3 :(得分:0)

好的,这里的问题是我们将CGBitmapContextCreateImage的返回定义为CGImageRef,它应该是CGImage。你的分配(我假设malloc)永远增加的原因是因为CGImage本身永远不会被释放。请尝试以下代码。此外,没有必要自动发布结果,因为它永远不会是Alloc' d。

在您再次使用分配的情况下进行更改之后,这次您希望不会看到实时字节的持续增加。

我在PC上输入了这个,所以如果你把它放到XCode中可能会出现语法错误;但是,这应该可以解决问题。

 // 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; 

答案 4 :(得分:0)

如果您正在使用垃圾收集,请使用CFMakeCollectable(posterFrame)。如果您正在使用传统的内存管理,那么它非常简单:

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

您将CFTypeRef(在本例中为CGImageRef)转换为Objective-C对象指针,向其发送-autorelease消息,然后将结果转换回CGImageRef。此模式适用于(几乎)任何与CFRetain()和CFRelease()兼容的类型。