CGImageRef Утечка памяти - PullRequest
       9

CGImageRef Утечка памяти

6 голосов
/ 31 декабря 2010

У меня утечка памяти при использовании этого пользовательского метода, который возвращает CGImageRef.Я не могу выпустить "cgImage" должным образом, потому что я должен вернуть его.Что мне делать?

- (CGImageRef)rectRoundedImageRef:(CGRect)rect radius:(int)radius
{
    CGSize contextSize = CGSizeMake(rect.size.width, rect.size.height);     
    CGFloat imageScale = (CGFloat)1.0;
    CGFloat width = contextSize.width;
    CGFloat height = contextSize.height;        
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, width * imageScale, height * imageScale, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    // Draw ...
    // Get your image
    CGImageRef cgImage = CGBitmapContextCreateImage(context);       
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    //CGImageRelease(cgImage); //If I release cgImage the app crashes.
    return cgImage;     
}

Ответы [ 4 ]

17 голосов
/ 31 декабря 2010

cgImage принадлежит вашему методу, вам нужно вернуть его и передать вызывающему абоненту ответственность за его освобождение через CFRelease.

Вы также можете вернуть CGImage, завернутый в UIImage например, как это:

UIImage *image = [UIImage imageWithCGImage:cgImage];
CFRelease(cgImage); //cgImage is retained by the UIImage above
return image;
10 голосов
/ 31 декабря 2010

Это общая проблема с объектами Core Foundation, поскольку в CF нет пула автоматического выпуска. На мой взгляд, у вас есть два варианта решения проблемы:

  1. Переименуйте метод в что-то вроде -newRectRoundedImageRef:radius:, чтобы сообщить вызывающей стороне, что он становится владельцем возвращенного объекта и отвечает за его освобождение.
  2. Оберните CGImageRef в автоматически выпущенный объект UIImage и верните его ([UIImage imageWithCGImage:]). Это, вероятно, то, что я бы сделал.
3 голосов
/ 31 декабря 2010

Вы можете автоматически выпустить Core Foundation-совместимый объект. это выглядит немного странно. :)

GC-безопасный способ выглядит так:

CGImageRef image = ...;
if (image) {
    image = (CGImageRef)[[(id)image retain] autorelease];
    CGImageRelease(image);
}

Ярлык, который безопасен на iOS, но больше не безопасен на Mac, таков:

CGImageRef image = ...;
if (image) {
    image = (CGImageRef)[(id)image autorelease];
}

Любой из них поместит изображение в пул автоматического выпуска и предотвратит утечку.

2 голосов
/ 10 сентября 2013

Как и предполагалось, мы использовали:

CGImageRelease(imageRef);

, но мы все еще получили утечку памяти.Нашим решением было обернуть код блоком

@autoreleasepool {}

, и это решило нашу проблему.

...