私はCocoa DesktopアプリケーションでCGImageRef(これはそうだと思います)にメモリリークの問題があります。私はここや他の場所で多くの質問を読んだことがあります.developer.apple.comのCore Graphicsメモリ管理のFAQを読んでください。たぶんthis questionはもっと似ていますが、解決策は役に立たなかったでしょう。CGImageRef MemoryLeak again
私の仕事は、保存された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の行のコメントを解除した場合、アプリは_magniHackを保持または(それが毎回異なる)画像をトリミングで、メッセージは「EXC_BAD_ACCESS」で、カーソルの第六動きにクラッシュします。私がそうしなければ、毎回メモリリークが起こるでしょう(頻繁な動きの間に漏れは数十MBです)。私が切り取った場合と同じ結果が得られますが、スケーリングされたイメージはリリースされません(ただし、リークははるかに多くなります)。
_magniHack - CGImageRefは、それがそのコードに一度だけ設定されている、プライベートインスタンス変数である:それは場合に役立ちます
-(void)storeFullScreen
{
if (_magniHack) {
CGImageRelease(_magniHack);
}
_magniHack = CGDisplayCreateImage(displays[0]);
}
は、私がプロジェクトでARCを使用しています。このことはまだ漏れを取り除くのに役立つことはありませんが。 私はどこかで_magniHackがリリースされていると思いますが、私はいつもstartとreleaseの最後にretainを実装しています。
ARCはObjective-Cクラス/オブジェクトではなく、Core Foundationタイプであるため、Quartzタイプには関係しません。 ARCはObjective-Cクラスの保持/解放のみを処理します。 –
ジョナサン、私はそれを知っています。これがCGImageReleaseを使ってイメージを公開する理由です。問題は私が解放すれば - それはつぶれる。私がしなければ - それは漏れる。 –