关于UIimage存储以及显示的问题


关于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] 的使用。因为加载图片时,内存不会飙升到手机的内存限制,但是如果多次使用以上两个耗时方法,会因为对象的使用内存无法得到及时的释放,从而累加,直至超出手机的限制,从而导致程序闪退。


以上是对遇到此问题的一个笔记,仅供参考,欢迎讨论。


文章作者: 小小学生
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小学生 !
评论
  目录