一、 SDWebImage原理简介
1.结构 (设计思路借鉴:提供多种接口,到底层调用到同一个方法,减少调用方对可选参数的传递)
UIImageView+WebCache和UIButton+WebCache直接为表层的 UIKit框架提供接口,
SDWebImageManger(SDWebImageManager是SDWebImage的核心类,也是我们经常接触到的类)负责处理和协调SDWebImageDownloader和SDWebImageCache, 并与UIKit层进行交互。SDWebImageDownloaderOperation真正执行下载请求;
SDWebImageManger详解:https://www.jianshu.com/p/246f6303cb6f
最底层的两个类为高层抽象提供支持。
SDWebImageCompat 是最基础的配置文件,为了兼容苹果各个平台
SDWebImageCompat 详解:https://www.jianshu.com/p/cfdd59d7df7c
SDWebImageDecoder sd解码图片这个类其实是UIImage的一个分类UIImage+ForceDecode,主要用来解码UIImage
SDWebImageDecoder 详解: https://www.jianshu.com/p/e631b4b2a214
结构关系图
结构详图(类图)
2.原理
一张图片加载的全过程:
- 我们在使用
SDWebImage
时调用了[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]];
这个简单的分类方法,然后就静静的等着图片被设置到UIImageView
类对象上。 - 经过一系列调用,我们首先来到
UIView+WebCache
分类中,在这个分类中,首先保障了图片加载的唯一性,然后就开始了核心的加载操作。 - 接着就进入了
SDWebImageManager
类中,在这个类中,首先去查找是否有缓存,没有缓存的话才去服务器下载。 - 想要查找缓存我们要进入
SDImageCache
这个类中,在这个类中,首先去内存中查看是否有对应的缓存,如果没有再去硬盘中查找是否有对应的缓存,但是从硬盘中获取的是图片的数据,要想获得图片还要经历解码、缩放和解压。当然如果都没有缓存的话就去下载。 - 负责下载的是
SDWebImageDownloader
这个类,在这个类中,将图片的下载操作封装成了自定义的一个类SDWebImageDownloaderOperation
,然后添加到了操作队列中。 - 当操作队列调用这个操作时,会调用操作对象的
- (void)start
方法,在重写的这个方法中,生成了任务对象dataTask
,并调用resume
开始执行任务。 - 因为
SDWebImageDownloaderOperation
类遵守了dataTask
对象的协议,所以dataTask
执行的结果会通过代理方法进行回调。在代理方法中,获取并保存了服务器返回的数据,并在任务执行结束后,对数据进行解码、缩放和解压。处理完成后就进行回调。 - 通过重重回调,要回调的数据沿着
SDWebImageDownloaderOperation
->SDWebImageDownloader
->SDWebImageManager
->UIView+WebCache
一路流动,其中流动到SDWebImageManager
中时对图片进行了缓存,最后在UIView+WebCache
中为UIImageView
设置了处理好的图片。 - 这就是
SDWebImage
加载图片的大体流程,当然还有非常多的小细节和小功能,这些就在以后对具体类的阅读中学习了。
运行时序图
运行流程图
3.源码解读(详解可看其中相关链接)
详解:https://juejin.im/post/5adff5636fb9a07aa213026b
二、SDWebImage4.0、5.0对比
4.0源码解析 :https://juejin.im/post/5bbec080e51d450e4d3021c0
5.0源码解析:https://www.jianshu.com/p/8af8fc7cd5bc
1.项目中结构(还是一样的,不像网上资料说的 变更了结构)
2.文件对比 5.0比4.0多出 61个文件(114+2-55)
3.SDAnimated 4.0只是为了处理GIF 5.0可以处理动画
4.Cache 充分体现SRP(单一职责)开发原则 ,缓存处理更加完备 专门的磁盘缓存处理类 内存缓存处理类
SDImageCache是SDWebImage的缓存类,是SDWebImage的重要组成部分,主要提供图片的缓存,和提取,分为内存缓存和磁盘缓存两种,因为SDWebImage的接口性设计,SDImageCache完全可以单独拿出来使用
详解:https://www.jianshu.com/p/f8f724bb0f4b
5.Coder(图片编解码器) 方法命名少了Web
SDWebImage里自己写了一个编解码管理器,用于实现编码,解码,压缩,缩小图片像素功能。涉及到的文件有SDWebImageCodersManager,SDWebImageCoder,SDWebImageImageIOCoder等等
详解 :https://www.jianshu.com/p/615d3178a508
6.Loader 图片下载 充分体现SRP(单一职责)开发原则,区分更加明显 类的功能更加单一 ,SDWebImageError 4.0没有 5.0专门的错误处理
SDWebImageDownloader和SDWebImageDownloaderOperation 是 SDWebImage的下载类,是SDWebImage的很重要的一个类,这个类主要负责图片的下载
详解:https://www.jianshu.com/p/a77fd7b09bd1
7.应用层 (多了4个文件,但跟实际使用没有多大关系)
/**
UIImage category for image metadata, including animation, loop count, format, incremental, etc.
*/
用于图像元数据的ui图像类别,包括动画、循环计数、格式、增量等
@interface UIImage (Metadata)
/**
Provide some commen method for `UIImage`.
Image process is based on Core Graphics and vImage.
*/
@interface UIImage (Transform)
为“uiimage”提供一些通用方法,拉伸,裁剪,圆角等等。
图像处理基于Core Graphics 和 vImage
8.引入SDWebImageContext / SDWebImageMutableContext
可以看到SDWebImageContext / SDWebImageMutableContext 其实就是
以 SDWebImageContextOption为key、id(指定类型或者协议)为value 的NSDictionary/NSMutableDictionary
typedef NSDictionary<SDWebImageContextOption, id> SDWebImageContext;
typedef NSMutableDictionary<SDWebImageContextOption, id>SDWebImageMutableContext;
而 SDWebImageContextOption 是一个可扩展的String枚举
typedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM;
SDWebImage定义了10个SDWebImageContextOption的key、对应的value类型和定义的位置
Key |
Value |
Define |
SDWebImageContextSetImageOperationKey |
NSString |
SDWebImageDefine.m |
SDWebImageContextCustomManager |
SDWebImageManager |
SDWebImageDefine.m |
SDWebImageContextImageTransformer |
id<SDImageTransformer> |
SDWebImageDefine.m |
SDWebImageContextImageScaleFactor |
CGFloat |
SDWebImageDefine.m |
SDWebImageContextStoreCacheType |
SDImageCacheType |
SDWebImageDefine.m |
SDWebImageContextDownloadRequestModifier |
id<SDWebImageDownloaderRequestModifier> |
SDWebImageDefine.m |
SDWebImageContextCacheKeyFilter |
id<SDWebImageCacheKeyFilter> |
SDWebImageDefine.m |
SDWebImageContextCacheSerializer |
id<SDWebImageCacheSerializer> |
SDWebImageDefine.m |
SDWebImageContextLoaderCachedImage |
UIImage/NSImage<SDAnimatedImage> |
SDImageLoader.m |
通过图片看下SDWebImageContext有多重要
从上图可以看到,SDWebImageContext就像一条「流水线」,把里面的参数项从最外层的View层一直传递到SDImageCache和SDWebImageDownloaderOperation。「流水线」经过的各个模块会从上去各自取自己感兴趣的东西使用(彩色实心箭头)
详解:https://www.jianshu.com/p/cfde8db5c051
9.协议化了很多重要的对象。(灵活)
之前要做某个操作必须用该对象 现在任何对象都可以 只要遵守了协议就可以
配合新引入的 SDWebImageContext/SDWebImageMutableContext 参数,保留快速使用特性的同时可以灵活的自定义高级功能
4.4 |
5.0 |
SDWebImageCacheSerializerBlock |
id<SDWebImageCacheSerializer> |
SDWebImageCacheKeyFilterBlock |
id<SDWebImageCacheKeyFilter> |
SDWebImageDownloader |
id<SDImageLoader> |
SDImageCache |
id<SDImageCache> |
SDWebImageDownloaderProgressBlock |
id<SDWebImageIndicator> |
详解:https://www.jianshu.com/p/cfde8db5c051
10.UIImage+GIF 方法变更
备注:
1.NS_EXTENSIBLE_STRING_ENUM 字符串类型枚举