Bitmap que causa fuga de memory en el dispositivo

Estoy usando la técnica de bitmap simple para convertir text en image, luego dividí esta image en ráster y más adelante estoy calculando el porcentaje de píxeles negros en cada rectángulo de ráster. Todo funciona bien en el simulador pero se bloquea en Device.here hay algún código relacionado

-(int)blackValue:(UIImage *)image rect:(CGRect)rect { int pixelInRect = (int)rect.size.width * rect.size.height; __block int blackCount = 0; ImageBitmap * imageBitmap = [[ImageBitmap alloc] initWithImage:image bitmapInfo:(CGBitmapInfo)kCGImageAlphaNoneSkipLast]; for (int x = 0; x <(int) rect.size.width; x++) { for (int y = 0; y < (int) rect.size.height; y++) { Byte * pixel = [imageBitmap pixelAtX:(int)rect.origin.x Y:(int)rect.origin.y]; Byte networking = pixel[0]; if (networking < 0.1) { blackCount++; } } } return blackCount/pixelInRect; } - (NSDictionary *)rasterizeBitmap:(UIImage *)image size:(CGFloat)size { CGFloat width =(int) (image.size.width/size); CGFloat height =(int) (image.size.height/size); NSMutableArray *fields = [NSMutableArray array]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { CGRect rect = CGRectMake(x * size, y * size, size, size); CGPoint center = CGPointMake(x * size + size/2.0, image.size.height - (y * size + size/2.0)); double black = [self blackValue:image rect:rect]; Field * field = [[Field alloc] init]; field.center = center; field.black = black; [fields addObject:field]; } } return @{@"width":@(width) , @"fields":fields}; } 

cuando bash correrlo en Profile obtuve el siguiente resultado

introduzca la descripción de la imagen aquí

¿Puede alguien sugerirme cómo puedo superar el problema de la memory?

El problema es que está asignando memory manualmente en su object ImageBitmap , pero nunca lo está liberando.

Los dos sospechosos son el context de bitmap ( context ) y los datos de bitmap ( contextData ). Ambos no están gestionados por ARC, por lo que querrás liberarlos tú mismo una vez que hayas terminado con ellos.

En ARC, simplemente puede implementar el método dealloc en su class ImageBitmap y poner allí su código de limpieza.

Por ejemplo:

 -(void) dealloc { CGContextRelease(context); // releases the bitmap context, if it was created (CGContextRelease checks for NULL) free(contextData); // releases the bitmap data (it was explicitly created, so no need to check) } 

También vale la pena señalar que debe hacer que init no esté disponible y marcar su inicializador designado.

Esto se debe a que no puede utilizar su imageFromContext y pixelAtX:Y: instance sin haber creado su instancia a través de su initWithSize:bitmapInfo: initializer personalizado, ya que crea el context de bitmap y asigna la memory para los datos de bitmap.

Por lo tanto, si creara su instancia llamando a init y llamara a uno de sus methods de instancia, lo más probable es que se bloquee.

Para remediar esto, puede marcar el método init como no disponible en su file ImageBitmap.h , y también marcar su initWithSize:bitmapInfo: como inicializador designado.

 -(instancetype) init NS_UNAVAILABLE; -(id)initWithSize:(CGSize)size bitmapInfo:(CGBitmapInfo)bmInfo NS_DESIGNATED_INITIALIZER; 

Todo lo que NS_UNAVAILABLE hace es impedirle crear su instancia simplemente llamando a init , lo que le obliga a usar sus inicializadores personalizados.

Si intenta hacer [[ImageBitmap alloc] init] , el comstackdor le mostrará el siguiente error:

introduzca la descripción de la imagen aquí

Todo lo que NS_DESIGNATED_INITIALIZER hace es asegurarse de que cualquier inicializador adicional en ImageBitmap debe crear nuevas instancias a través de su inicializador y le mostrará la siguiente advertencia si no lo hace:

introduzca la descripción de la imagen aquí

Vea aquí para get más información sobre NS_DESIGNATED_INITIALIZER .

Ahora, en la práctica, estas son realmente solo formalidades ya que eres el único que va a usar esto, y sabes que tienes que usar los inicializadores personalizados. Sin embargo, es bueno tener estas formalidades correctas si alguna vez quieres compartir tu código con otras personas.