2016-06-17 3 views
1

J'aimerais sauver UIImage en NSArray au niveau local comme PNG. Cependant, lorsque j'ai utilisé UIImagePNGRepresentation dans une boucle for, la mémoire a considérablement augmenté même s'il y a déjà un @autoreleasepool. J'ai donc essayé de convertir UIImage en CGImageRef et d'utiliser ImageIO framework pour sauvegarder l'image. Puis, en utilisant CGImageRelease() pour libérer de la mémoire dans chaque boucle.UIImage sauver la mémoire cause PNG fuite

-(void)saveImage:(CGImageRef)image directory:(NSString*)directory filename:(NSString*)filename { 
@autoreleasepool { 
    CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", directory, filename]]; 
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL); 
    CGImageDestinationAddImage(destination, image, nil); 

    if (!CGImageDestinationFinalize(destination)) 
     NSLog(@"ERROR saving: %@", url); 

    CFRelease(destination); 
    CGImageRelease(image); 
} 

}

for (int i = 0; i < array.count; i++) { 

    NSDictionary *src = array[i]; 

    NSString *localPath = [SPLDPath stringByAppendingPathComponent:@"realImg"]; 
     NSFileManager *file = [NSFileManager defaultManager]; 
    if (![file fileExistsAtPath:localPath]) { 
     [file createDirectoryAtPath:localPath withIntermediateDirectories:NO attributes:nil error:nil]; 
    } 
    NSString *fileName = [NSString stringWithFormat: @"ScreenShot_%d.png", i]; 

    CGImageRef cgRef=[src[@"image"] CGImage]; 
    [self saveImage:(cgRef) directory:localPath filename:fileName]; 

} enter image description here Cependant, la mémoire a diminué, un nouveau problème est arrivé. Mon application a été plantée en raison d'une mémoire trop libre. Parce que le UIImage a été publié par CGImageRelease(), mais ARC a également essayé d'envoyer un message delloc à l'objet zombie avant la fin de l'application. Comment puis-je libérer CGImageRef sans entrer en collision avec ARC?

Répondre

0

Ne pas invoquer CGImageRelease() sur la propriété CGImage, puisque votre code ne tient pas ref INCR à cet objet. Vous ne publiez dans ce cas que si votre code incrémente explicitement le ref quelque part.

+0

thx pour votre réponse. Mais si je n'ai pas libéré le CGImageRef, la mémoire continuera à croître, que puis-je faire pour libérer de la mémoire dans chaque boucle? –

+0

Le code que vous avez publié ci-dessus tente de libérer avec CGImageRelease() lorsque l'image n'est pas conservée. Corrigez cela en premier, puis adressez les autres problèmes dans votre code. Par exemple, vous pouvez simplement passer un nom de fichier dans une méthode, faire en sorte que cette logique charge le fichier PNG et ensuite libérer toutes les références maintenues. Contrairement à ce que vous faites maintenant, qui contient toutes les images PNG décompressées en mémoire. Vous ne pouvez pas conserver beaucoup d'images décompressées en mémoire en même temps. Fixez cela et vous devriez être mieux lotis. – MoDJ