【发布时间】:2012-03-19 11:22:08
【问题描述】:
我的 Cocoa 桌面应用程序中的 CGImageRef 存在内存泄漏问题(我猜是这样)。我在这里和其他任何地方都阅读了很多问题,请阅读 developer.apple.com 上的 Core Graphics 内存管理常见问题解答。也许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 是在某个地方发布的,但我找不到,在哪里,因为我总是在开始时实现保留并在最后释放。
【问题讨论】:
-
ARC 与 Quartz 类型无关,因为它们是核心基础类型,而不是 Objective-C 类/对象。 ARC 仅处理 Objective-C 类的保留/释放。
-
乔纳森,我知道。这就是我使用 CGImageRelease 发布图像的原因。问题是如果我释放 - 它会粉碎。如果我不这样做 - 它会泄漏。
标签: objective-c cocoa cgimage