我的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并在最后释放。
答案 0 :(得分:1)
这很老了,但我的情况也有同样的问题。 问题是释放色彩空间而实际上没有副本。 CGImageGetColorSpace(裁剪)为您提供指向现有色彩空间的指针,您不应该释放它。它不是为您创建的副本。 那是我的情况。当我注意到(我使用互联网上的代码来缩放图像) CGDisplayCreateImage(显示[0])不再崩溃。
答案 1 :(得分:0)
实际上,我只在必要时使用Core Graphics
来消除这种泄漏,即在抓住屏幕后我将其包裹到NSImage*
中,并且我只使用它。但它仍然很有趣,上面的代码出了什么问题。