SDWebImage

SDWebImage

SDWebImage 是一些小项目用的比较多的网络图片缓存库,思路比较简单,代码也不是很多。我猜实现起来的主要工作在于那些通用的业务逻辑吧,再简单的东西想做的通用还是要考虑的很复杂的,尤其是好的开源库需要考虑到各种场景、各种可能的使用需求。

花晚上的时间看了一下源码,感谢作者的开源精神,到目前还在不停的更新功能,现在有4.0-beta版。源码就不贴了,可以在SDWebImage获得,叙述一下思路吧。


实现思路

思路几句话就能说明白了。输入一个链接,SDWebImage 输出一个图片。

通常情况 SDWebImage 拿到链接后,会先在内存cache中查找这张图片;如果没有,则去磁盘中查找;如果没有,就去下载获得。
获得图片后会先更新内存缓存,然后更新磁盘缓存。
应用退出时会清空内存缓存,然后更具情况缩小磁盘缓存。

这些逻辑主要由三个类完成:

  • SDWebImageDownloader 提供图片下载功能
  • SDImageCache 提供图片缓存管理
  • SDWebImageManager 组合管理下载和缓存的逻辑,主要对外提供功能

SDWebImageDownloader

提供单例。

使用 SDWebImageDownloaderOperation 执行下载任务,对于相同的下载任务 SDWebImageDownloader 中有一个字典存储,相同的任务不会产生多个下载,而是会把回调记录下来,和之前的下载一起回调。
这里使用了一个队列来操作字典,避免多线程竞争。这里使用了一个并发队列,但观察发现串型队列就足够了。

下载任务 SDWebImageDownloaderOperation 会被加入到 SDWebImageDownloaderdownloadQueue(NSOperationQueue) 中,并发数默认为6,超时时间为15秒。

SDWebImageDownloaderOperation 中通过 NSURLSessiondelegate 来获取下载回调,同时处理一些授权相关的事件。


SDImageCache

提供单例。

持有一个 NSFileManager,所有对其的操作都在一个特定的串型队列中。
当获取图片时,会先在 memory-cache 检查,memory-cache 是一个在内存警告时能自动清理的 NSCache

如果 memory-cache 中没有,就去磁盘中取图片。取完如果有,并且需要保留在memory-cache,那就在内存中保存一份。

当应用被杀死时,磁盘的缓存会被清理超出预期size的部分。


SDWebImageManager

提供单例。

UIImageView+WebCache 设置图片时的主要逻辑都在 SDWebImageManager 中,其中包含一个 SDImageCacheSDWebImageDownloader

SDWebImageManager 中获取图片时,首先在 SDImageCache 中查找图片,如果没有再通过 SDWebImageDownloader 去下载,下载后在 SDWebImageManager 中会通过 SDImageCache 来缓存一下。


最后

粗暴的叙述一下思路,源码就不贴了,不多。我看的是 3.8.2 版本。


iOS Objective-C open source SDWebImage