SDWebImage框架核心剖析 by:西瓜
各个类作用:
SDWebImageDownloader :可单独下载图片,专门用来下载图片和优化图片的。
SDWebImagePrefetcher:预下载图片,方便后续使用,以及图片下载的优先级的管理。处理和下载缓存还是用SDWebImageManager。
SDWebImageDownloaderOperation:继承于NSOperation 处理下载任务。
UIView+WebCacheOperation:用来记录图片加载的Operation,方便后期取消和移除图片加载的的Operation。
SDImageCache :用来处理内存缓存和磁盘缓存的,磁盘缓存为异步的。
UIImageView+WebCache:集成SDWebImageManager的缓存功能到UIImageView中,方便简单调用。
UIImageView+HighLightedWebCache:跟UIImageView+WebCache类似,只不过用于加载HighLighted状态的图片。
UIButton+WebCache:跟UIImageView+WebCache一样只是将对象由UIImageView改成了UIButton。
MKAnnotationView+WebCache 跟UIImageView+WebCache类似。
SDWebImageManager:这个是UIImageView+WebCache的付出者,主要作用在于将图片下载(SDWebImageDownloader)和图片缓存(SDImageCache)组合起来。
SDWebImageDeCoder:图片解码器,用于图片载完成后的解码。
NSData+ImageContentType:用于获取图片的格式(jpeg, png等)。
UIImage+Gif:用于加载GIF图片数据的格式。
UIImage+MultiFormat:根据不同的二进制数据转成UIImage对象。
UIImage+WebP:用于解码并加载WebP的图片。
知道了各个类的作用之后,大家也是可以将其中部分类,脱离框架去单独使用。
当调起SDWebImageManager的图片加载方法:
SDWebImageManager会先拿key去内存缓存读取,这个key为url中不变的地方,这里默认的是图片的url。
如果读取到: 直接给到SDWebImageManager。
如果没有读取到:这里就会开启一个异步线程。这个异步线程主要做什么呢?
1.拿到这个key 去MD5加密一下。
2.用MD5好的key去磁盘中的缓存读取。
读取磁盘时会先从沙河里面找,没有就去bundle了。
如果在磁盘的缓存中读取到了:
1.将磁盘的缓存同步到内存缓存中。(如果内存过小,会清扫内存缓存)。
2.然后返回给到SDWebImageManager。
如果没有:
就会调用SDWebImageDownloader 去异步下载图片,下载到了完成会给到SDWebImageDeCoder解码,解码成功后会在主线程宣告解码成功 ,并且图片会同步到磁盘缓存,图片缓存中。并且在这里会回调到主线程给中给到imageView去显示。
细节剖析:
1.下载图片的队列执行顺序为,先进先出,后进后出这二种。
2.SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。
3.当同时下载多张图片,就会有多个线程去访问某个属性的情况,为了保证线程安全,使用了 dispatch_barrier_sync 来分步执行添加到 barrierQueue 中的任务。目的:同一时间只有一个线程能对 URLCallbacks 进行操作。
针对以上信息,大家可以把整个架构在脑海里面过一遍。