项目中有多图展示的collection和tableView,后台提供的图片多是那种高清大图,一张有的甚至好几百kb,当网速较差或者一般的时候,快速滑动collection或者tableView,强行去加载这些大图片,这时候,程序有时候会出现异常卡顿,严重的时候甚至会直接崩溃,查看原因,控制台返回时内存溢满。
相信大家大部分用的都是SDWebImage来加载图片,既然出现这种问题,想必通用的SDWebImage加载图片的方法已经无法满足我们的需求了。所以要深入SDWebImage中进行处理。
我们使用SDWebimage肯定都会做三件事,一判断本地是否有这张图,二有的时候直接从本地取图片,三没有的时候去网络下载。
通过对SDWebImage代码的分析,发现他都会调用下面这个方法:
1 | - (nullable UIImage *)diskImageForKey:(nullable NSString *)key { |
其中有这行代码:
1 | UIImage *image = [UIImage sd_imageWithData:data]; |
图片取出来的时候就已经巨大无比,占用了很大的内存,导致内存来不及释放就崩溃。
点进这个sd_imageWithData方法内部,发现这里面对图片的处理是直接按照原大小进行的,如果图片过大将导致占用了大量内存。所以我们需要在这里对图片做一次等比的压缩。
1.在UIImage+MultiFormat这个类里面添加如下压缩方法
1 | +(UIImage *)compressImageWith:(UIImage *)image |
然后在UIImage+MultiFormat文件中调用如下代码
如下图:
1 | if (data.length/1024 > 128) { |
2.在SDWebImageDownloaderOperation中将接下来的data数据用第一步中等比转换后的image来获取。
在didCompleteWithError代理方法中,如下图:
添加代码
1 | NSData *data = UIImageJPEGRepresentation(image, 1); |
到此结束。
接下来你会发现在运行程序时候,加载大图片的时候,再也不会有那种卡顿甚至崩溃的现象了,内存变化基本不大,自动释放也来得及了。