iPhone客户端图片下载与缓存的实现

    目前对远程图片的本地缓存实现的第三方库很多比如SDWebImage,还有一些第三方HTTP库都会扩展对图片的缓存,那为什么我还要实现一个自己的图片下载与缓存呢?一般情况下图片的下载是没有什么特别需求的,关键是我们对图片的本地存储方案有一些特别的要求,我们客户端的图片是要分成两部分进行缓存,而且都要缓存到本地文件系统里,一部分是要定时进行清理的,一部分是要永久存储在本地的,在图片失效的情况下才会清理这些图片。这样的话我们改第三库的存储方案其实也可以,但是考虑到往往第三方库都会携带很多额外赠送的功能,而且代码量都比较大会一定程度上增加项目程序包的大小,我只需要一个轻量级的图片下载与缓存方案。所以我决定自己根据第三方库SDWebImage的思路简化出一个自己的版本来。

    具体的实现方案就是Cache(内存)--  Disk(本地文件系统)--  Internet(网络请求),一般在内存中进行映射的话不需要异步,但是对Disk和Internet的访问为了避免阻塞UI主线程就需要进行异步操作了。缓存的key一般都会采用图片URL在MD5之后生成的字符串。

    内存缓存最好使用苹果提供的NSCache,NSCache可以限制每一个存储条目的大小和整体缓存的数目,避免占用过多内存,但是NSCache的失效策略苹果并没有在官方文档中有说明。因为本地存储会分为两个路径进行存储,所以在内存中的缓存也进行了两部分存储,当我们指定相应的缓存策略时,我在实现的时候并没有只去映射策略相应的那部分内存缓存(Disk同理),而是根据缓存策略先去判断哪部分内存缓存和Disk存储,另外一个内存和Disk缓存后判断,如果是永久存储的策略,而图片是存储在暂时缓存的内存中或者缓存在暂时缓存的Disk目录下,就自动的对本图片进行转存,存到永久缓存目录下。其他另外三种映射关系不进行处理。缓存映射关系如图(稍后奉上):

    然后是Disk缓存,这个需要注意的就是在存储图片或者获取图片的时候最好进行异步操作。(下面这点我还没有做过验证)需要注意一点的是,我发现iOS对图片的加载有一点延迟,当我有一张图片缓存到本地暂时缓存Disk了,下一次开启程序内存中还没有该图片的缓存,而我直接以永久缓存策略的方式根据URL获取图片时,发现该图片存在了暂时缓存Disk目录下,这时我就要进行转存,根据这张图片在暂时缓存Disk下的目录实例化了一个UIImage用于返回给UIImageView显示,然后立马把这张照片也存到永久缓存Disk目录下,这时我应该删除暂时缓存Disk目录下得那张图片,可是如果我删了的话,用于显示的那个UIImage就会报错提示图片不存了。我暂时的想法就是iOS对图片的加载一定是延迟加载,可能是只有要显示UIImage或者使用UIImage的时候才会加载图片具体的内容。 

    还有就是网络请求了,SDWebImage有一个非常值得学习的地方就是对同一个URL的请求的处理,如果同一个URL的图片请求,前面的那个还没有处理完,后面的会对前面的进行取消,这样的好处就是避免的多次下载。但是我有一个考虑为什么不是保留前面的请求而忽略后面的呢,我给自己的回答是前面的可能超时或者当时处在一个网络不好的情况下是无法返回图片,这样就造成在这次无法下载返回之前都不能下载这张图片了,而新的请求最有可能取得新的结果。当然我们自己的网络请求要是忽略原生的本地response缓存的。

    实现代码(对SDWebImage的提炼):https://github.com/Joywii/SGWebImage

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值