2010-12-31 20 views
5

Tengo una pérdida de memoria cuando uso este método personalizado que devuelve un CGImageRef. No puedo lanzar "cgImage" correctamente porque tengo que devolverlo. ¿Qué debo hacer?CGImageRef Memory leak

- (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

Tuve una fuga similar. Pruebe mi respuesta aquí: http://stackoverflow.com/a/23669476/3631310 – Vlad

Respuesta

15

cgImage es propiedad de su método, tiene que volver y darle la responsabilidad a la persona que llama para liberarlo a través CFRelease.

También puede volver el CGImage envuelto dentro de una instancia UIImage, así:

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

Este es un problema general con objetos Fundación Core, porque no hay piscina autorelease en la FQ Tal como lo veo, usted tiene dos opciones para resolver el problema:

  1. cambiar el nombre del método a algo así como -newRectRoundedImageRef:radius: de decir la persona que llama que asume la propiedad del objeto devuelto y responsable de soltarlo.
  2. Envuelva CGImageRef en un objeto autorellenado UIImage y devuelva eso ([UIImage imageWithCGImage:]). Eso es probablemente lo que haría.
3

Puede liberar automáticamente un objeto compatible con Core Foundation. simplemente se ve un poco inestable. :)

La forma GC-safe es así:

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

El acceso directo, que es seguro en iOS, pero no más segura en el Mac, es la siguiente:

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

Cualquiera de los dos colocará la imagen en un grupo de autorrelease y evitará una fuga.

2

Como se sugirió, hemos utilizado:

CGImageRelease(imageRef); 

pero todavía tiene una pérdida de memoria. nuestra solución era para envolver con un bloque de código

@autoreleasepool {} 

y que resolver nuestro problema.

+0

+1 solo responde que mencioné @autoreleasepool - que fue la cura para mis males. – Damo

+0

Todavía no lo lanza adecuadamente tbh –