GitHub 中文社区第三方框架解析iOS学习

项目总结 2017.06.15 ---- SDWebimage、

2017-06-16  本文已影响309人  你看见我的小象了吗

声明:
我不是在外包公司工作,目前就职于北京红黄蓝教育机构,旗下产品有竹兜育儿、红黄蓝亲子园等平台服务类APP。竹兜育儿日活4000 + ,关于日活,如果说是开发人员的原因我实在是没有办法反驳,公司运营真的不听我的,曾经做过相关建议,但是没有什么效果,后来安静的做我自己的开发。大学没有毕业就在红黄蓝上班,现在准备离职了,如果有合适的公司,可以联系我,谢谢。

SDImageCacheConfig.png
  1. 使用第三方应用之前,请用一点时间去阅读源码,哪怕试一次简单的升级,也要花点时间去阅读一下,毕竟,没有人会无缘无故的改写代码
  2. 能够进行封装就简单的封装下,粒度自己控制就好,但是好的粒度控制对于系统升级、代码重构、扩展有事半功倍之效

一、SDWebImage 的坑(可能很多人说过,但是自己整理一下,留作自用,给他人提供另外的思路也好)

  1. SDWebImage 4.0.0 版本,新增了 SDImageCacheConfig 类,此类里面包含了关于 Cache 的配置项,可以自行进行更改,如果有需要的话。

代码示例

 SDImageCacheConfig.m
  _shouldDecompressImages = NO;
  _shouldCacheImagesInMemory = NO;
 ```
PS: 如果贵公司是对性能要求很高的公司,FPS 必须上60,响应时间控制及其严格等等,我相信不单单会只从 iOS 方面下手,而是多方面去优化,有时候移动端需要服务很大代价能完成的东西,后端多写两行代码就可以解决了。
2. SDWebImageDownloader、SDWebImageManager 两类中还是存在加载大图,占用内存超高的现象
* Manager 内部调用了 Download,Download 内部调用了SDWebImageDownloaderOperation,所以如果出现加载图片内存飙升的情况可以直接定位到 operation 里面看看,是哪里的代码出现了问题。同时使用 Instruments 看一下内存占用情况,定位到具体代码位置, 之前出现过 SD 对原图没有做任何处理直接转化为 data 的情况,导致内存直接飙升。

二、AFN & YYCache 缓存处理、AFN 组下载文件

1. AFN 大多数的开发人员都会使用,并且也会根据业务进行封装,我原来也是这样做的,屡试不爽,直到遇到这次的项目,我彻底的被项目打败了,项目里面最少1500张图片、50 PDF 文件、40多视频文件,都要求能够进行离线缓存,而且是一键缓存,先不说需求到底合理与否,做是一定能做出来的。事实证明,后来我还是做出来了,而且做得还好。不卡不闪退,运行流畅。
* AFN 配合 YYCache 做缓存
 思路是每次请求时,首先根据URL 读取本地缓存的 data,存在即展示,请求成功之后,异步保存成功的数据,再次返回成功的数据,刷新视图。YYCache 会自动处理内部的缓存逻辑,具体的可以看看 YYCache 的源码部分,很好理解,这样至少不用写蹩脚的 sql 语句放在数据库里面,还要考虑数据库的读写性能,全部交由自动处理,省去了很多的麻烦。

![AFN & YYCache.png](http://upload-images.jianshu.io/upload_images/1226381-a66ac4698299a48f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
  这只是简单的提供一下关于缓存数据的思路,后续需要去完善的地方还有很多,留在后续来说。  

1. AFN 对于UIkit 框架同样有一套自己的支持,只是一直以来用的人不是很多。但是同样有可取之处。  
*  AFImageDownloader 相对于  SDWebImageDownloader 来说,在请求相同的的大图的情况下 AFN 所占用的内存要小于 SD,而且不会存在内存飙升的情况,对于内存的控制表现良好,一直都是比较平稳的,占用释放都很好。但是缓存策略(cachePolicy)的设置一定要设置好,因为如果requestCachePolicy 设置为 NSURLRequestReturnCacheDataElseLoad 或 NSURLRequestReturnCacheDataDontLoad 时,会一直加载缓存的数服务器返回的新数据并不会显示。幸运的是,AFN 中 AFNetworkReachabilityManager 提供了网络切换的回调方法,可以在回调方法里进行设置。开始的时候,我在应用中采取的就是这样的策略。但是由于我的资源文件实在是太大,而且网络情况太不稳定,会造成缓存的读写混乱,有可能此时正在写入缓存,而网络断掉,开始读取缓存,比较难处理。所以我针对这样的情况,替换成为了以下解决方案。   
2. AFN 文件下载功能  
资源文件的类型已经确定,仅有图片、PDF 、Video 三种资源文件,采用队列组的方式进行下载,首先去请求图片文件,全部图片文件下载成功之后下载 PDF 文件,然后再去下载 Video 文件,因为Video 文件很大占用的时间较长,以及配合业务逻辑所以放在最后下载。 

![dispath_group 队列下载文件.png](http://upload-images.jianshu.io/upload_images/1226381-c96a94068484ca3c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 创建组,循环中加入组,成功之后离开组,全部完成之后发送通知,完全能够满足要求
* 具体使用方法,下次再说

![AFNDownload 方法的封装.png](http://upload-images.jianshu.io/upload_images/1226381-24461533f56dbe2f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
*  根据文件的不同类型,文件保存路径不同,这点很重要  
http://cyznres.rybbaby.com/20170508155721332_75.jpg?imageView2/1/w/150/h/130/q/100/format/png
http://cyznres.rybbaby.com/20170508155721332_75.jpg?imageMogr2/format/jpg/size-limit/5120k!  
因为 AFN 获取文件名的方式是直接获取  `response.suggestedFilename` 以上两个链接的图片文件名是一样的,但是获取到的图片质量大小都是不同的,前者为缩略图后者为高清图,所以一定一定要放在不同的路径下进行保存。这一点很重要
* 下载失败的处理,我处理的方式是,下载失败之后,将 URL 添加到 fails 数组里,当全部文件下载完成之后,遍历 fails 新开组进行下载,最多三次。  

三、AFN & SDWebImageCache 读取文件

![显示图片的方法.png](http://upload-images.jianshu.io/upload_images/1226381-e20ca8ff4a977a15.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* 读取 SD 缓存,存在缓存直接显示
* 缓存不存在,判断文件是否已经被下载,如果文件已经被下载,直接读取本地文件显示
* 文件没有下载,使用 SD 进行显示,并且缓存至 Disk

四、整体流程图

![AFN & SDWebImage 配合使用流程图.png](http://upload-images.jianshu.io/upload_images/1226381-a1d874e791507842.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



 



上一篇下一篇

猜你喜欢

热点阅读