2012-03-19 10 views
1

私は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を実装しています。

+0

ARCはObjective-Cクラス/オブジェクトではなく、Core Foundationタイプであるため、Quartzタイプには関係しません。 ARCはObjective-Cクラスの保持/解放のみを処理します。 –

+0

ジョナサン、私はそれを知っています。これがCGImageReleaseを使ってイメージを公開する理由です。問題は私が解放すれば - それはつぶれる。私がしなければ - それは漏れる。 –

答えて

0

実際には、必要ならばCore Graphicsを使用してこのリークを取り除きました。つまり、画面をつかんでからNSImage*にラップして、それだけで動作します。しかし、それはまだ面白いです、上記のコードで何が間違っていた。

1

これはかなり古いですが、私の場合も同じ問題がありました。 問題は色空間を実際にコピーせずに解放していました。 CGImageGetColorSpace(cropped)は、既存の色空間へのポインタを与えます。解放しないでください。それはあなたのために作成されたコピーではありません。 それは私の場合でした。私が気づいたとき(私はインターネットから画像を拡大するためにコードを使用しました) CGDisplayCreateImage([0]表示)はもはやクラッシュしていませんでした。

関連する問題