图片选择、压缩性能问题分析

1.图片选择

随着项目越来越大,图片视频选择样式越来越丰富,后期维护成本越来越高。项目初期所有的图片视频选择放在一个 viewController看着还挺满意,毕竟样式单一,逻辑还算清晰。可是后面样式越来越多,每次处理这部分代码,都要花费大半天时间来理解之前的逻辑。如果某一处逻辑考虑不全面,就会引出crash,所以每次迭代又要调整这部分代码时候,都是小心翼翼,严重影响项目进度。

终于在一次迭代中, PM提出图片选择增加集合的概念,便于几十屏照片的手机用户快速找到需要的图片。这次不能再往视频图片选择里面添加代码了,必须进行重构。

图片选择、压缩性能问题分析_第1张图片

重构前一个MYImagePickerViewController里面码完所有代码。

重构后框架如下:

MYImageAssetManager:单例,实现相册集合数据源逻辑。初始化时,更新相册集合和相册中照片和视频的张数,且监听系统相册中资源更新。

MYMediaPickerViewController:父类,处理公共逻辑。1.请求访问授权 ;2.通过对应的PHAssetCollection获取图片视频展示;3.处理图片上下滑动缓存逻辑。

MYVideoPickerViewController:子类,处理视频选择逻辑。视频最小长度,拍照入口等等。

MYImagePickerViewController:子类,处理图片选择逻辑。单选、多选,选折后裁剪等等。

MYImageAlbumsViewController:顶部图片选择集切换。当MYImagePickerViewController进行图片集切换时,添加到父控制器MYImagePickerViewController上。

 MYImageVideoPickerViewController:发图片发视频切换,如上图界面。在子控制器,MYImagePickerViewController和MYVideoPickerViewController之间切换。

下面分析MYImageAssetManager中部分代码:     

.h文件中的供外界访问的属性和方法                                                             

 videoAssetCollection是MYVideoPickerViewController控制器的视频集合。                imageDefaultCollection是MYImagePickerViewController控制器默认的图片集合。          imageAssetCollections是MYImageAlbumsViewController控制器的图片集数组。      

图片选择、压缩性能问题分析_第2张图片
图片选择、压缩性能问题分析_第3张图片
图片选择、压缩性能问题分析_第4张图片


2.图片选择内存占用高和界面上下滑动卡顿问题解决

图片选择多张大图时,很容易引发界面卡顿,内存占用率高,内存不足闪退等问题。

1>将获取原图方法- requestImageForAsset:targetSize:contentMode:options:resultHandler:修改为- requestImageDataForAsset:options:resultHandler:,在相同图片大小上,内存降低了很多。后者直接返回二进制数据,不渲染。

2>获取缩略图用- requestImageForAsset:targetSize:contentMode:options:resultHandler:,获取到UIImage后,可以用UIImageJPEGRepresentation转换为NSData,传递图像数据。UIImageJPEGRepresentation转化时候会有损耗,若项目中图片数据传递的较多,超过其带来的影响,所以可以忽略。

3>图片在传递中用NSdata,若要用到UIImage,就这样转换:[UIImage imageWithData:imageData]。

4>界面卡顿问题,可以将图片进行缓存, 用PHAsset的localIdentifier作为缓存的key。

下面两个方法分别用于获取缩略图和原图。

图片选择、压缩性能问题分析_第5张图片
图片选择、压缩性能问题分析_第6张图片


3.图片上传压缩,内存再次高占用闪退

图片压缩上传时,先获取原图,然后压缩。如果原图很大,压缩时内存再次高紧张。以下两个步骤可以解决此问题。

1>异步队列改为同步队列

图片压缩之前放在异步队列里面,当几十个图片并发压缩时,内存突然一下飙升,当所有图片压缩完成后,内存突然下降。就在突然飙升那一段,如果手机内存有限,应用就闪退了。之后改为同步队列,内存不会突然飙升,而是小幅上升依次处理每个压缩。代码如下:

图片选择、压缩性能问题分析_第7张图片

这样子解决了部分问题,但是依然有闪退存在。

2>以“自动释放池”降低内存峰值

图片选择、压缩性能问题分析_第8张图片

autoreleasepool自动释放池用于存放那些需要在稍后某个时刻释放的对象,清空自动释放池时,系统会向其中的对象发送release消息。创建自动释放池语法如下:                   

                                              @autoreleasepool{...  }                                                                     

花括号定义了自动释放池的范围,自动释放池在左花括号处创建,并于右花括号处自动清空。位于自动释放池范围内的对象,将在此范围末尾处收到release消息。

因此,在压缩图像时,可以通过autoreleasepool控制应用的内存峰值,使其不致过高。

你可能感兴趣的:(图片选择、压缩性能问题分析)