再次CGImageRef MemoryLeak

时间:2012-03-19 11:22:08

标签: objective-c cocoa cgimage

我的Cocoa桌面应用程序中有CGImageRef(我猜,就是这样)的内存泄漏问题。我在这里和其他任何地方都阅读了很多问题,请阅读developer.apple.com上的核心图形内存管理常见问题解答。也许this question与我的相似,尽管解决方案没有帮助。

我的任务是从已保存的CGImage缩放区域15 * 15并返回NSImage *,每次鼠标移动都会完成。

-(NSImage*)getScaledAreaInX:(int)x andY:(int)y
{
    // Catching image from the screen
CGImageRef fullscreen = CGImageRetain(_magniHack);
    // Cropping
int screenHeight = CGImageGetHeight(fullscreen);
CGRect fixedRect = CGRectMake(x-7, screenHeight-y-8, 15, 15);
CGImageRef cropped = CGImageCreateWithImageInRect(fullscreen, fixedRect);

    // Scaling
int width = CGImageGetWidth(cropped)*8;    // New width;
int height = CGImageGetHeight(cropped)*8;  // New height;

CGColorSpaceRef colorspace = CGImageGetColorSpace(cropped);
CGContextRef context = CGBitmapContextCreate(NULL, width, height,
                                             CGImageGetBitsPerComponent(cropped),
                                             CGImageGetBytesPerRow(cropped),
                                             colorspace,
                                             CGImageGetAlphaInfo(cropped));
CGContextSetInterpolationQuality(context, kCGInterpolationNone);


CGContextDrawImage(context, CGRectMake(0, 0, width, height), cropped);
CGImageRef scaled = CGBitmapContextCreateImage(context);

    // Casting to NSImage
NSImage *image = [[NSImage alloc] initWithCGImage:scaled size:NSZeroSize];

    // Releasing memory
CGImageRelease(fullscreen);
CGColorSpaceRelease(colorspace);
CGContextRelease(context);
//CGImageRelease(cropped); // Can't do: will crash; In what situations can free?
cropped = NULL;
CGImageRelease(scaled);
scaled = NULL;

return image;
}

如果我取消注释CGImageRelease行,应用程序将在光标的第6次移动时崩溃,在保留_magniHack或裁剪图像(每次都不同)时,消息为“EXC_BAD_ACCESS”。如果我不这样做,每次都会有内存泄漏(在频繁的移动过程中,泄漏几十MB)。如果我发布裁剪,我得到的结果相同,但不释放缩放图像(虽然泄漏会更多)。

_magniHack - CGImageRef,它是私有实例变量,在该代码中只设置一次:

 -(void)storeFullScreen
 {
     if (_magniHack) {
         CGImageRelease(_magniHack);
     }
     _magniHack = CGDisplayCreateImage(displays[0]);
 }

如果有帮助,我会在项目中使用ARC。虽然这件事仍然无法摆脱泄漏。   我猜_magniHack是在某个地方发布的,但我找不到,因为我总是在启动时实现retain并在最后释放。

2 个答案:

答案 0 :(得分:1)

这很老了,但我的情况也有同样的问题。 问题是释放色彩空间而实际上没有副本。 CGImageGetColorSpace(裁剪)为您提供指向现有色彩空间的指针,您不应该释放它。它不是为您创建的副本。 那是我的情况。当我注意到(我使用互联网上的代码来缩放图像) CGDisplayCreateImage(显示[0])不再崩溃。

答案 1 :(得分:0)

实际上,我只在必要时使用Core Graphics来消除这种泄漏,即在抓住屏幕后我将其包裹到NSImage*中,并且我只使用它。但它仍然很有趣,上面的代码出了什么问题。