SDWebImage源码解析

SDWebImage是我们非常常用的一个关于图片下载缓存的框架。下面的源码分析是基于版本3.8。下面是gitHub上的介绍:

SDWebImage源码解析_第1张图片

主要作用:

1、为UIiamgeView,UIbutton  等控件加载网络图片,并且进行缓存管理

2、一个异步图片下载工具

3、一个异步的内存和硬盘的图片缓存,提供自动的缓存处理

4、异步的图片解码

5、保证相同的URL不会多次下载

6、保证不合法的URL不会被多次下载

7、保证主线程不会被阻塞

8、自定义

9、使用GCD 和 ARC

为什么使用SDWebImage而不是NSURLCache或是AFN?

1、在IOS 5之后可以使用NSURLCache 进行http缓存,但是每次缓存的是原始数据,每一次使用的时候,需要将原始数据解析成UIImage,导致额外的数据解析和内存占用,AFN就是使用NSURLCache进行缓存的。

2、UIImageView中使用image对象的时候,图片的解码是在主线程中运行的!而SDWebImage会强制将解码操作放到子线程中。(PNG,jpeg图片对象,转换为位图对象)

3、使用NSCache作为内存缓存,避免了对象的重复copy,并且保存的是位图对象,避免了重复的解码。

4、SDWebImage 完全绕过了Http请求关于缓存的控制,大大加快了缓存速度。

根据图片的url缓存,所以一旦改变图片,必须改变地址?(不会去判断服务器关于缓存处理的response header )对于类似facebook 头像这样的例子,可以使用下面的方式,这种方式,会参考请求头。

5、提供了大量的关于图片的扩展选择。

当我们调用这个sd_setImageWithURL,这个方法的时候发生了什么?

1、停止所有和这个View相关的Operation。

这里还有一个operation 字典:UIView+WebCacheOperation  有一个关联对象,用来保存这个View相关的Operation


SDWebImage源码解析_第2张图片
operation字典


SDWebImage源码解析_第3张图片
UIView+WebCacheOperation的cancle 当前所有相关的Operation

(相关类的介绍:

UIImageView (WebCache):

1、提供相关的下载方法

UIView (WebCacheOperation)

1、提供与view相关的loadOperation(字典),可以通过这个字典取消该View相关的Operation)

2、SDWebImageManager的downloadImageWithURL的方法

(1)、非法Url判断

(2)、定义一个SDWebImageCombinedOperation,用这个Operation管理下载和缓存的Operation,并把它加到runningOperations中

(3)、产生缓存的key,这里的缓存的key,可以进行自定义


SDWebImage源码解析_第4张图片
自定义缓存key

(相关类介绍:

SDWebImageOperation

1、定义的一个基础协议,带有cancle方法

SDWebImageCombinedOperation

1、混合Operation,包含缓存Operation还有管理下载Operation

SDWebImageManager

SDWebImageManager(单例)

1、中间层,调用缓存,和下载(管理所有的Operation)

2、提供SDWebImageManagerDelegate(作为扩展),还有三种block

)

3、SDImageCache的queryDiskCacheForKey方法,开始寻找磁盘缓存和内存缓存

(1)、内存缓存,使用的NSCache(避免重复拷贝)

(2)、一个IOQueue,进行磁盘缓存的查询,进行异步查询


在io队列里面异步查询

(3)、如果磁盘中存在这张图片,那么进行判断对应的图片格式(包括动态图)

设置图片的方向(Orientation),scale,并且进行解码工作。这里强制进行异步解码,将编码之后的图片格式(png,jpeg)转换成位图对象。


SDWebImage源码解析_第5张图片
进行缓存查找操作

相关的类:

SDImageCache(单例)

1、缓存管理,缓存配置,缓存清理,缓存查找(异步执行)

2、内存缓存,使用的是位图,磁盘缓存使用的是编码之后的图片

UIImage (ForceDecode)

1、图片解码,相关格式图片图像,转换为位图对象

强制解码:将编码之后的image对象转换为位图(点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的)

一般下载或者从磁盘获取的图片是PNG或者JPG,这是经过编码压缩后的图片数据,不是位图,要把它们渲染到屏幕前就需要进行解码转成位图数据,而这个解码操作比较耗时,iOS默认是在主线程解码,所以SDWebImage将这个过程放到子线程了。

同时因为位图体积很大,所以磁盘缓存不会直接缓存位图数据,而是编码压缩后的PNG或JPG数据。

4、当没有缓存时候,使用SDWebImageDownloader进行下载,

(1)、将所有的callback放在一个字典数组中管理。(用url作为key)。

(2)、封装request对象,加入用户自带的一些配置

注:为了避免重复下载,默认,不进行NSUrlCache缓存,不使用系统的缓存


避免重复下载

(3)产生SDWebImageDownloaderOperation,下载操作

(4)设置这个operation 的相关属性,比如优先级,还有executionOrder,执行顺序(先进后出或是先进先出),(实现的方式,是通过Operation的相互依赖)


SDWebImage源码解析_第6张图片
关于执行顺序的枚举值
SDWebImage源码解析_第7张图片
执行顺序设定的实现

相关的类:

SDWebImageDownloader

1、图片下载类,图片的下载管理

2、提供大量扩展(下载设置)

SDWebImageDownloaderOptions

SDWebImageDownloaderExecutionOrder,下载的顺序

SDWebImageDownloaderProgressBlock

SDWebImageDownloaderCompletedBlock

SDWebImageDownloaderHeadersFilterBlock

maxConcurrentDownloads(最大并发数)

3、操作callBack使用的的调度方式, dispatch_barrier_sync,dispatch_barrier_async管理barrierQueue(类似于锁?),之后添加的Operation,会等这个任务执行之后才会继续执行

5、使用SDWebImageDownloaderOperation,进行下载,在下载过程中,调用progressBlock,下载结束,调用completeBlock。拿到网络数据,转成图片格式,设置方向,scale,进行图片解码,返回的图片是位图对象

管理下载操作,3版本使用的是NSURLConnection,之后使用的是NSURLSession(异步下载)

(1)、提供后台下载,开启运行循环(不然代理不能正常调用)

(2)在NSURLConnection的代理中,处理下载功能

(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 拿到服务器响应,判断是否正确下载

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data下载过程管理(调用progressBlock),这里提供边下载,边显示的功能

SDWebImage源码解析_第8张图片
下载图片,进行异步的强制解码

6、回到SDWebImageManager,

(1)处理Image对象,如果实现了相关的代理方法就调用代理方法,

(2)之后使用imageCache,保存图片信息。位图对象直接保存到内存缓存中,编码图片,保存到磁盘中。(这里是否能在之前就直接保存到磁盘,节省一段图片编码的过程)。内存中保存位图,是为了避免重复解码。磁盘中保存编码之后的图片是为了节省空间。

(3)从全局的Operation字典,移除相关的Operation


SDWebImage源码解析_第9张图片
将下载后的图片进行缓存

7、回到UIImageView (WebCache),回到主线程,设置图片,调用结束


SDWebImage源码解析_第10张图片
更新UI,回到主线程

其他注意的点:

1、缓存清理,当收到这三个通知的时候进行缓存的清理


SDWebImage源码解析_第11张图片

缓存清理的策略,这里的IO操作都是异步处理的。

(1)删除过期缓存(苹果官方规定最长的缓存周期是1周)

(2)计算当前缓存文件的总大小,比较设置的最大缓存,如果超出的话,那么就继续删除(按照缓存文件创建的顺序),直到小于最大缓存为止


缓存策略

2、SDWebImagePrefetcher,这个类,提供提前缓存图片的方法(可以用来作用于banner等),提供批量的下载。


SDWebImage源码解析_第12张图片

3、对于UIView (WebCacheOperation),当我们移除Operation的时候,发生了什么?其实取消的是SDWebImageCombinedOperation

(1)、取消cacheOperation

(2)、执行cancelBlock,这里的cancleBlock,关闭的就是下载的Operation

(3)、将这个Operation,移除整个Operation字典


SDWebImage源码解析_第13张图片


SDWebImage源码解析_第14张图片

你可能感兴趣的:(SDWebImage源码解析)