【问题标题】:CGImageRef MemoryLeak againCGImageRef MemoryLeak 再次
【发布时间】: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


【解决方案1】:

这已经很老了,但在我的情况下我遇到了同样的问题。 问题是在没有实际副本的情况下释放色彩空间。 CGImageGetColorSpace(cropped) 给你一个指向现有颜色空间的指针,你不应该释放它。它不是为您创建的副本。 那是我的情况。当我注意到时(我也使用互联网上的代码来缩放图像) CGDisplayCreateImage(displays[0]) 不再崩溃了。

【讨论】:

    【解决方案2】:

    实际上,我仅在必要时使用Core Graphics 来消除此泄漏,即在抓取屏幕后将其包装到NSImage* 中,然后只使用它。不过还是很有意思,上面的代码哪里出了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多