关于UIImage存储的那些事
最近在做一款APP时,需要存储以及加载大量的本地图片,在写代码过程中,遇到一些问题,导致内存暴涨,导致cash.
将拍摄或者从相册选取的图片存入沙盒
/// 将图片保存到本地
+ (void)saveImageToLocal:(UIImage*)image fileName:(NSString*)fileName {
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", fileName]];
// 图片转base64字符串
NSData *data = UIImageJPEGRepresentation(image, 1.0);
// 写入文件
BOOL flag = [data writeToFile:filePath atomically:YES];
if (flag) {
NSLog(@"保存成功");
}
}
由于图片不能被压缩,要保证图片不失帧,所以用到了苹果官方提供的方法 **UIImageJPEGRepresentation(image, 1.0)**这个方法,会在不失帧的情况下,将图片转化成data二进制流。由于此方法比较耗时,所以,尽量减少在循环中大量调用此方法。
存储时,最好直接将图片写入沙盒。不要做多余的转化
显示的时候,直接从沙盒读取,直接读取图片,不要再用 [UIimage imageWithData:data] 来再次转化,因为此方法,会使你的内存得不到释放,且,由于是系统提供的方法,在ARC环境下,不能手动释放。
可能有人会说,加一个@autoreleasepool {}自动释放池,但是并不能及时的释放掉,创建的Data或者image,即使是加了 data = nil image = nil 也不能正确的释放掉,已经创建好的对象。
所以,取图片时,也必须直接取出
/// 从本地获取图片
+ (UIImage*)getImageFromLocal:(NSString*)fileName {
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", fileName]];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
return image;
}
尽可能的减少对 [UIimage imageWithData:data] 的使用。因为加载图片时,内存不会飙升到手机的内存限制,但是如果多次使用以上两个耗时方法,会因为对象的使用内存无法得到及时的释放,从而累加,直至超出手机的限制,从而导致程序闪退。
以上是对遇到此问题的一个笔记,仅供参考,欢迎讨论。