Я хотел бы сохранить 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?
THX для вашего ответа. Но если бы я не выпустил CGImageRef, память будет продолжать расти, что я могу сделать, чтобы выпустить память в каждом цикле? –
Код, который вы опубликовали выше, пытается освободить CGImageRelease(), когда изображение не удерживается. Исправьте это, а затем рассмотрите другие проблемы в вашем коде. Например, вы можете просто передать имя файла в метод, иметь эту логическую загрузку PNG и затем отпустить любые удерживаемые ссылки. В отличие от того, что вы делаете сейчас, в котором хранятся все распакованные изображения PNG в памяти. Вы просто не можете хранить много декомпрессированных изображений в памяти одновременно. Исправьте это, и вам должно быть лучше. – MoDJ