將Array中的UIImage取出戚扳,存為本地PNG圖片
1. UIImage存PNG圖片
通過UIImagePNGRepresentation()方法保存PNG格式圖片時(shí),由于ARC機(jī)制分歇,會(huì)產(chǎn)生大量臨時(shí)的autorelease對象维哈,需要等待runloop的autoreleasepool銷毀時(shí)才能銷毀這些對象脖捻。由于for循環(huán)中的臨時(shí)對象無法及時(shí)釋放,造成內(nèi)存持續(xù)增長邮绿,最終導(dǎo)致程序的不穩(wěn)定,甚至崩潰拓巧。
1.1 代碼-for循環(huán)存PNG圖片
objc
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];
}
}
objc
1.2 Instruments中內(nèi)存持續(xù)增長
如下圖所示斯碌,盡管代碼中創(chuàng)建了自己的@autoreleasepool,但是臨時(shí)對象仍然沒有被銷毀肛度,仍然以自己的節(jié)奏高速增長傻唾。
stackoverflow建議
I had the same issue with UIImagePNGRepresentation and ARC. My project is generating tiles and the allocated memory by UIImagePNGRepresentation was just not removed even when the UIImagePNGRepresentation call is part of a @autoreleasepool.
I didn't had the luck that the issue is disappeared by adding a few more @autoreleasepool's like it did for JHollanti.
My solution is based on EricS idea, using the ImageIO Framework to save the png file.
題主通過增加@autoreleasepool可以釋放調(diào)用UIImage和UIImagePNGRepresentation來保存PNG圖片時(shí),持續(xù)增加的內(nèi)存。但是我們的代碼不能釋放冠骄,回答者DerMarcus建議使用ImageIO框架伪煤。
2 ImageIO存PNG圖片
2.1 代碼
2.1.1 使用ImageIO編寫存圖方法
objc
-(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);
}
}
objc
2.1.2 for循環(huán)存PNG圖片
objc
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];
}
objc
2.2 Instruments中內(nèi)存先增后減
注釋: 增長峰值為截圖產(chǎn)生的內(nèi)存