CGImageRef MemoryLeak снова - PullRequest
       5

CGImageRef MemoryLeak снова

1 голос
/ 19 марта 2012

У меня проблема с утечкой памяти в 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 выпущен где-то, но я не могу найти, где, потому что я всегда реализую сохранение на старте и выпуск в конце.

Ответы [ 2 ]

1 голос
/ 04 февраля 2015

Это довольно старый, но у меня была та же проблема в моем случае. Проблема заключалась в том, чтобы выпустить цветовое пространство, фактически не имея его копии. CGImageGetColorSpace (обрезано) дает вам указатель на существующее цветовое пространство, и вы не должны его освобождать. Это не копия, созданная для вас. Это был мой случай. Когда я это заметил (я использовал код из интернета для масштабирования изображения) CGDisplayCreateImage (display [0]) больше не падал.

0 голосов
/ 24 января 2013

На самом деле, я избавился от этой утечки, используя Core Graphics только в случае необходимости, т. Е. После захвата экрана я обертываю его в NSImage*, и я работаю только с ним. Но все равно интересно, что не так с кодом выше.

...