2010-12-31 48 views
5

Mam wyciek pamięci przy użyciu tej niestandardowej metody, która zwraca CGImageRef. Nie mogę poprawnie zwolnić "cgImage", ponieważ muszę je zwrócić. Co mam zrobić?CGImageRef wyciek pamięci

- (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;  
} 
+0

Miałem podobny przeciek. Wypróbuj moją odpowiedź tutaj: http://stackoverflow.com/a/23669476/3631310 – Vlad

Odpowiedz

15

cgImage jest własnością metodę, trzeba go zwrócić i dać odpowiedzialność rozmówcy do uwolnienia go przez CFRelease.

Można również zwrócić CGImage owinięty wewnątrz instancji UIImage coś takiego:

UIImage *image = [UIImage imageWithCGImage:cgImage]; 
CFRelease(cgImage); //cgImage is retained by the UIImage above 
return image; 
10

Jest to ogólny problem z obiektów Fundacja Rdzeń ponieważ nie ma basenu autorelease w CF. Jak ja to widzę, masz dwie możliwości rozwiązania problemu:

  1. zmienić nazwę metody do czegoś podobnego -newRectRoundedImageRef:radius: powiedzieć rozmówcy, że przejmie na własność zwracanego obiektu i odpowiedzialny za zwolnienie go.
  2. Zawiń CGImageRef w autorejestrowanym obiekcie UIImage i zwróć ([UIImage imageWithCGImage:]). Prawdopodobnie to bym zrobił.
3

Możesz autorelease obiekt zgodny z Core Foundation. to po prostu wygląda trochę niesmacznie. :)

Sposób GC-safe jest tak:

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

Skrót, który jest bezpieczny na iOS, ale nie jest już bezpieczny na komputerze Mac, jest to:

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

Albo jeden umieści obraz w puli autorelease i zapobiegnie wyciekowi.

2

Jak sugeruje, użyliśmy:

CGImageRelease(imageRef); 

ale wciąż mieliśmy wyciek pamięci. nasz roztwór do zawijania kodu z bloku

@autoreleasepool {} 

i rozwiązywać problemu.

+0

+1 odpowiedź tylko na wspomniany @autoreleasepool - który był lekiem na moje zło. – Damo

+0

Nadal nie wypuszcza go poprawnie tbh –