SDWebImage源码分析
1.概述
SDWebImage是iOS开发中,被广泛使用的一个第三方开源库,提供了图片从加载、解析、处理、缓存、清理等一些列功能,让我们能够专心于业务的处理。本篇会从SDWebImage的源码,来一步步分析,让我们更加的熟悉和了解它,以达到更好的应用的目的。
SDWebImage最常用的方法就是下面这个,我们在实际开发中,大部分时间只是用到了这个方法:
[self.imageView sd_setImageWithURL:[NSURL URLWithString:@"url"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
SDWebImage的设计是极其的优雅和简洁, 主要的功能就是这么一行代码, 而其中复杂的实现细节全部隐藏在这行代码之后。
下图是SDWebImage官方的类图:
通过对上面图片的分析,我们可以将SDWebImage的类分为三大类型:视图分类;工具类;核心类。
1.1视图分类
这部分包含的类主要有如下几个:
UIButton(WebCache):
为UIButton
类加载图片的方法。比如正常情况下、点击情况下的image属性和背景图片等。MKAnnotationView(WebCache):
为MKAnnotationView
类添加各种加载图片的方法。UIImageView(WebCache):
为UIImageView
类添加加载图片的方法。UIImageView(HighlightedWebCache):
为UIImageView
类添加高亮状态下加载图片的方法。FLAnimatedImageView(WebCache):
为FLAnimatedImageView
类添加加载动态的方法,这个分类需要引入FLAnimatedImage
框架。SDWebImage
推荐使用这个框架来处理动态图片(GIF)的加载。UIView(WebCache):上面几个
分类,都会调用本分类的sd_internalSetImageWithURL
方法来做图片加载请求,具体是通过SDWebImageManager
调用来实现的。它还实现了Operation取消、ActivityIndicator的添加与取消。同时通过UIView+WebCacheOperation
分类来管理请求的取消和记录工作。
1.2工具类
NSData+ImageContentType
: 根据图片数据获取图片的类型,比如GIF、PNG等。SDWebImageCompat
: 该配置文件主要是兼容Apple的其他设备,包含很多宏定义以及一个根据key修改图片尺寸的方法。SDImageCacheConfig
: 用来管理缓存配置信息。比如是否解码、是否允许iCloud、是否允许内存缓存、缓存时间等。默认的缓存时间是一周。UIImage+MultiFormat
: 获取UIImage对象对应的data、或者根据data生成指定格式的UIImage,其实就是UIImage和NSData之间的转换处理。UIImage+GIF
: 对于一张图片是否GIF做判断。可以根据NSData返回一张GIF的UIImage对象,并且只返回GIF的第一张图片生成的GIF。如果要显示多张GIF,使用FLAnimatedImageView
。SDWebImageDecoder
: 根据图片的情况,做图片的解码处理,并且根据图片的情况决定如何处理解码。
1.3核心类
SDImageCache
: 负责SDWebImage的整个缓存工作,是一个单例对象
。缓存路径处理、缓存名字处理、管理内存缓存和磁盘缓存的创建和删除、根据指定key获取图片、存入图片的类型处理、根据缓存的创建和修改日期删除缓存。SDWebImageManager
: 这个类是一个单例。
拥有一个SDWebImageCache
和SDWebImageDownloader
属性分别用于图片的缓存和加载处理。为UIView及其子类提供了加载图片的统一接口。管理正在加载操作的集合,还有就是各种加载选项的处理。SDWebImageDownloader
: 实现了图片加载的具体处理,如果图片在缓存则从缓存区加载。如果缓存不存在,则直接创建一个。同时管理NSURLRequest对象请求头的封装、缓存、cookie的设置。加载选项的处理等功能。管理Operation之间的依赖关系。SDWebImageDownloaderOperation
: 一个自定义的并行Operation子类。这个类主要实现了图片下载的具体操作、以及图片下载完成以后的图片解码、Operation生命周期管理等。FLAnimatedImageView
: 动态图片的数据通过ALAnimatedImage对象来封装。FLAnimatedImageView
是UIImageView
的子类。通过它完全可以实现动态图片的加载显示和管理。并且对UIImageView
做了流程优化。
2.实现流程
SDWebImage为我们实现了图片加载、数据处理、图片缓存等一些列工作。下面我们通过官方的图来看一下相关操作的流程:
通过上图,我们知道SDWebImage加载的过程是首先从缓存中加载数据,缓存加载是优先从内存缓存中加载,然后才是磁盘加载。如果没有缓存,才从网络上加载。网络成功加载图片以后,存入本地缓存。
3.SDWebImage源码解读
- SDWebImage之工具类;
- SDWebImage之SDWebImageCompat;
- SDWebImage之SDWebImageManager;
- SDWebImage之SDImageCache;
- SDWebImage之SDWebImageDownloader;
- SDWebImage之SDWebImageDownloaderOperation;
- SDWebImage之UIView+WebCache。
4.总结
通过对SDWebImage开源库的学习,大致有如下几点让我收获较多:
- 解耦的思想:在我们实际的项目开发中,往往容易忽略解耦的重要性,最终导致代码量越来越多,也越来越乱,增大了代码的维护成本,也间接的降低了代码的质量。在SDWebImage中,核心类是SDWebImageManager,在这个类中,它又把两项重要的职责:缓存管理、下载管理,拆分给SDImageCache和SDWebImageDownloader,这样,作为核心类的SDWebImageManager,功能和思想以及代码的维护相对来说要容易很多。
- 清晰的功能流程:从图片的下载到图片显示到视图上,SDWebImage的流程非常清晰。首先从缓存中加载数据,缓存加载又是优先从内存缓存中加载,然后才是磁盘加载。最后如果缓存没有,才从网络上加载。同时网络成功加载图片以后,存入本地缓存。
- 优秀的性能细节处理:通过使用GCD和NSOperation的结合使用,来提升用户性能上的体验提升;
- 简洁的API:采用Category,让我们能像使用视图的原生API一样,简易的进行操作。
无善无恶心之体,
有善有恶意之动,
知善知恶是良知,
为善去恶是格物。