У меня проблема с утечкой памяти в CGImageRef (наверное, так) в моем приложении Cocoa Desktop.Я читал много вопросов здесь и везде, читал FAQ по управлению памятью Core Graphics на developer.apple.com.Возможно этот вопрос больше похож на мой, хотя решение не помогло.
Моя задача - масштабировать область 15 * 15 из сохраненного CGImage и в результате вернуть 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»,В противном случае будет происходить утечка памяти каждый раз (при частых перемещениях утечка составляет десятки МБ).Тот же результат, который я получаю, если я освобождаю обрезанное изображение, но не выпускаю масштабированное изображение (хотя утечка будет намного больше).
_magniHack - CGImageRef, это частная переменная экземпляра, она устанавливается только один раз в этом коде:
-(void)storeFullScreen
{
if (_magniHack) {
CGImageRelease(_magniHack);
}
_magniHack = CGDisplayCreateImage(displays[0]);
}
Я использую ARC в проекте, если это помогает.Хотя эта вещь все еще не может помочь избавиться от утечек.Я предполагаю, что _magniHack выпущен где-то, но я не могу найти, где, потому что я всегда реализую сохранение на старте и выпуск в конце.