UIGraphicsGetImageFromCurrentImageContext memory leak con vistas previas

Estoy tratando de crear vistas previas de imágenes en un PDF, pero tengo algunos problemas con el lanzamiento de la memoria.

Escribí un algoritmo de prueba simple que cíclica en el problema, la aplicación se bloquea cerca de la 40 ª iteración :

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:@"myPdf.pdf"]; CFURLRef url = CFURLCreateWithFileSystemPath( NULL, (CFStringRef)pdfPath, kCFURLPOSIXPathStyle, NO ); CGPDFDocumentRef myPdf = CGPDFDocumentCreateWithURL( url ); CFRelease (url); CGPDFPageRef page = CGPDFDocumentGetPage( myPdf, 1 ); int i=0; while(i < 1000){ UIGraphicsBeginImageContext(CGSizeMake(768,1024)); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); CGContextFillRect(context,CGRectMake(0, 0, 768, 1024)); CGContextSaveGState(context); CGContextTranslateCTM(context, 0.0, 1024); CGContextScaleCTM(context, 1.0, -1.0); CGContextDrawPDFPage(context, page); CGContextRestoreGState(context); // -------------------------- // The problem is here (without this line the application doesn't crash) UIImageView *backgroundImageView1 = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; // -------------------------- UIGraphicsEndImageContext(); [backgroundImageView1 release]; NSLog(@"Loop: %d", i++); } CGPDFDocumentRelease(myPdf); 

La línea antes mencionada parece generar una pérdida de memoria, sin embargo, los instrumentos no muestran problemas de memoria;

¿Puedo escapar de este tipo de error? ¿Alguien puede explicarme de qué manera? ¿Hay otras maneras de mostrar vistas previas de un pdf?

ACTUALIZAR

Creo que el problema no es el lanzamiento de UIImage creado por el método UIGraphicsGetImageFromCurrentImageContext() sino el lanzamiento de UIImageView creado con esta imagen de liberación automática.

He dividido la línea de código en tres pasos:

 UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext(); UIImageView *myImageView = [[UIImageView alloc] init]; [myImageView setImage: myImage]; // Memory Leak 

La primera y la segunda líneas no crean pérdidas de memoria, así que creo que el método UIGraphicsGetImageFromCurrentImageContext no es el problema.

También intenté lo siguiente, pero el problema persiste:

 UIImageView *myImageView = [[UIImageView alloc] initWithImage:myImage]; 

Creo que hay una pérdida de memoria en el lanzamiento de un UIImageView que contiene un UIImage con la propiedad de liberación automática.

Traté de escribir mi objeto UIImageView heredando un UIView como se explica en este hilo .

Esta solución funciona pero no es muy elegante, es una solución, preferiría usar el objeto UIImageView para resolver el problema de memoria.

El problema es este:

 UIGraphicsGetImageFromCurrentImageContext() 

devuelve un UIImage liberado automáticamente. El grupo de liberación automática conserva esta imagen hasta que el código devuelve el control al runloop, lo que no hace durante mucho tiempo. Para resolver este problema, debería crear y drenar un grupo de autorelease nuevo en cada iteración (o cada pocas iteraciones) de su ciclo while.

Sé que es una vieja pregunta, pero hace unas horas me golpeo la cabeza contra la pared. En mi aplicación repetidamente llamando

 UIImage *image = UIGraphicsGetImageFromCurrentImageContext() 

en un bucle se aferra a la memoria a pesar de que llamo image = nil; No estoy seguro de cuánto tiempo la aplicación mantendrá la memoria antes de liberarla, pero ciertamente es lo suficientemente larga como para que mi aplicación reciba una advertencia de memoria y luego se cuelgue.

Pude resolverlo finalmente envolviendo el código que llama / usa la imagen de UIGraphicsGetImageFromCurrentImageContext () en @autoreleasepool. Así que tengo:

 @autoreleasepool { UIImage *image = [self imageWithView:_outputImageView]; //create the image [movie addImage:image frameNum:i fps:kFramesPerSec]; //use the image as a frame in movie image = nil; } 

Espero que pueda ayudar a alguien.

¿Este código se está ejecutando en el hilo principal? La documentación de UIGraphicsGetImageFromCurrentImageContext ( enlace ) dice que debe ejecutarse de esa manera.

He tenido el mismo problema al trabajar con imágenes grandes. Agregar un relleno a una imagen o aplicar un filtro resultó con 200MB de asignación de memoria sin soltarlo mientras la imagen estaba en la pantalla.

Encontré una forma efectiva de solucionar este problema:

 extension UIImage { func release() -> UIImage? { guard let data = UIImageJPEGRepresentation(self, 1.0) else { return nil } return UIImage(data: data) } } 

También lo intenté con UIImagePNGRpresentación, pero parece que tampoco libera la asignación.

su línea de falla puede actualizarla como sigue

obtener una UIimage fuera de bucle

rendered_image = UIGraphicsGetImageFromCurrentImageContext ();

Intereting Posts