第三方库SDWebImage①缓存-①缓存不更新问题

必备知识架构-第三方库SDWebImage①缓存-①缓存不更新问题

[Toc]

一、背景

后台图片内容换了,但是url还是老的,手机就用了缓存,没有从后台更新图片。

主要问题表现在哪里呢?
很多app都有用户的概念,用户一般都会有头像,基本上都上传到服务器上,而服务器往往也支持在pc端更新头像(比如微博、QQ等)。
如果你的头像使用SDWebImage设置的,那么你会发现,pc端更新头像后,客户端可能(往往)不会自动更新!!!

二、解决

问:使用SDWebImage如何加载url不变,但图片已经变化的图片。

答:解决方法可以有如下几种:

  1. 让服务器更新url,也就是说服务器端如果更新了头像,那么就生成新的url(推荐)

    后台给的url中增加字段,表示图片是否更新,比如增加一个timestamp字段.图片更新了,就更新下这个字段;
    对客户端来说,只要这个timestamp字段变了,整个url就不一样了,就会从网络取图片。比如http://xxx/xx? timestamp=xxx
    也可以添加图片文件的md5来表示文件是否更新,比如http://xxx/xx? md5=xxx。并且md5比时间戳要好,这是强校验。时间戳在服务器回滚或者服务器重启的时候会有特殊的逻辑。不过大多数时候时间戳也够用了。
    ====这个方案客户端不用改,后台改动也不会太大。====强烈推荐

  2. 客户端只使用内存缓存,不使用磁盘缓存,那么下次启动时候就会重新下载,从而得到最新的了。(缺点:本次使用过程中没能看到最新图片。且即使之后下载到最新图片了,由于只使用内存缓存,不使用磁盘缓存。导致程序关闭又打开之后,缓存就没了,需要访问网络,重新加载图片)

    SDWebImageCacheMemoryOnly这个参数对解决这个问题有帮助,只用内存缓存,不用磁盘缓存,App关了再开,肯定会重新下载,不会出现服务器和手机缓存图片不一致的情况。

  3. 客户端使用SDWebImageRefreshCached,同时让服务器端支持cache-control。

    SDWebImageRefreshCached,这个参数就是为了解决url没变但是服务器图片改变的问题,很适合当前的场景。方案就是磁盘缓存不自己实现了,直接使用NSURLCache。记得AFNetworking的大神Matt就曾经嘲笑过SDWebImage的缓存是多此一举,还不如系统的NSURLCache好用。

    SDWebImageRefreshCached参数设置之后,会怎么样?

    • 不使用SDWebImage提供的内存缓存和硬盘缓存

    • 采用NSURLCache提供的缓存,默认情况下有效时间只有5秒

    • 图片不一致的问题是解决了,不过效果跟不使用缓存差别不大。个人建议这个参数还是不要用为好,为了一个小特性,丢掉了SDWebImage最核心的特色。

      1
      2
      3
      4
      >   [imageview sd_setImageWithURL:[NSURL URLWithString:url]	
      > placeholderImage:nil
      > options:SDWebImageRefreshCached];
      >
  4. 不使用SDWebImage,自己控制缓存,用系统API实现(NSURLCache)实现。(缺点还是和3一样,得服务端配合更改。)

    主要也是和使用SDWebImageRefreshCached时候一样,会涉及到Cache-Control(设定缓存有效时间,默认是5s)Last-Modified/If-Modified-Since(时间戳)Etag/If-None-Match(标签,一般用MD5值)

附:其他options

SDWebImageRetryFailed表示就算下载失败也会再次尝试(不把下载失败的的url加入黑名单)

参考文章: