SDWebImage
SDWebImage
SDWebImage 是一些小项目用的比较多的网络图片缓存库,思路比较简单,代码也不是很多。我猜实现起来的主要工作在于那些通用的业务逻辑吧,再简单的东西想做的通用还是要考虑的很复杂的,尤其是好的开源库需要考虑到各种场景、各种可能的使用需求。
花晚上的时间看了一下源码,感谢作者的开源精神,到目前还在不停的更新功能,现在有4.0-beta版。源码就不贴了,可以在SDWebImage获得,叙述一下思路吧。
实现思路
思路几句话就能说明白了。输入一个链接,SDWebImage 输出一个图片。
通常情况 SDWebImage 拿到链接后,会先在内存cache中查找这张图片;如果没有,则去磁盘中查找;如果没有,就去下载获得。
获得图片后会先更新内存缓存,然后更新磁盘缓存。
应用退出时会清空内存缓存,然后更具情况缩小磁盘缓存。
这些逻辑主要由三个类完成:
- SDWebImageDownloader 提供图片下载功能
- SDImageCache 提供图片缓存管理
- SDWebImageManager 组合管理下载和缓存的逻辑,主要对外提供功能
SDWebImageDownloader
提供单例。
使用 SDWebImageDownloaderOperation 执行下载任务,对于相同的下载任务 SDWebImageDownloader 中有一个字典存储,相同的任务不会产生多个下载,而是会把回调记录下来,和之前的下载一起回调。
这里使用了一个队列来操作字典,避免多线程竞争。这里使用了一个并发队列,但观察发现串型队列就足够了。
下载任务 SDWebImageDownloaderOperation 会被加入到 SDWebImageDownloader 的 downloadQueue(NSOperationQueue) 中,并发数默认为6,超时时间为15秒。
SDWebImageDownloaderOperation 中通过 NSURLSession 的 delegate 来获取下载回调,同时处理一些授权相关的事件。
SDImageCache
提供单例。
持有一个 NSFileManager,所有对其的操作都在一个特定的串型队列中。
当获取图片时,会先在 memory-cache 检查,memory-cache 是一个在内存警告时能自动清理的 NSCache。
如果 memory-cache 中没有,就去磁盘中取图片。取完如果有,并且需要保留在memory-cache,那就在内存中保存一份。
当应用被杀死时,磁盘的缓存会被清理超出预期size的部分。
SDWebImageManager
提供单例。
UIImageView+WebCache 设置图片时的主要逻辑都在 SDWebImageManager 中,其中包含一个 SDImageCache 和 SDWebImageDownloader。
从 SDWebImageManager 中获取图片时,首先在 SDImageCache 中查找图片,如果没有再通过 SDWebImageDownloader 去下载,下载后在 SDWebImageManager 中会通过 SDImageCache 来缓存一下。
最后
粗暴的叙述一下思路,源码就不贴了,不多。我看的是 3.8.2 版本。