2016-06-17 3 views
1

Я хотел бы сохранить UIImage в NSArray локально, как PNG. Однако, когда я использовал представление UIImagePNGR для цикла, память сильно выросла, хотя уже существует @autoreleasepool.UIImage save to PNG вызывает утечку памяти

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

    @autoreleasepool { 
     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 *screenShotImg = [localPath stringByAppendingPathComponent:[NSString stringWithFormat:@"ScreenShot_%d.png", i]]; 
     NSData *PNGData = UIImagePNGRepresentation(src[@"image"]); 
     [PNGData writeToFile:screenShotImg atomically:YES]; 
    } 
} 

Так что я попытался преобразовать UIImage в CGImageRef и использовать рамки ImageIO, чтобы сохранить изображение. Затем с помощью CGImageRelease() выпустить память в каждом цикле.

-(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 была уменьшена память, однако, новый вопрос случилось. Мое приложение разбилось из-за чрезмерно выпущенной памяти. Поскольку UIImage был выпущен CGImageRelease(), но ARC также попыталась отправить сообщение delloc объекту зомби до конца приложения. Как я могу освободить CGImageRef, но не столкнуться с ARC?

ответ

0

Не вызывайте CGImageRelease() в свойстве CGImage, так как ваш код не содержит incr ref к этому объекту. Вы только выпустили бы в этом случае, если бы ваш код явно увеличивал количество ссылок.

+0

THX для вашего ответа. Но если бы я не выпустил CGImageRef, память будет продолжать расти, что я могу сделать, чтобы выпустить память в каждом цикле? –

+0

Код, который вы опубликовали выше, пытается освободить CGImageRelease(), когда изображение не удерживается. Исправьте это, а затем рассмотрите другие проблемы в вашем коде. Например, вы можете просто передать имя файла в метод, иметь эту логическую загрузку PNG и затем отпустить любые удерживаемые ссылки. В отличие от того, что вы делаете сейчас, в котором хранятся все распакованные изображения PNG в памяти. Вы просто не можете хранить много декомпрессированных изображений в памяти одновременно. Исправьте это, и вам должно быть лучше. – MoDJ

Смежные вопросы