SDWebImage Source Probe: WebCache

 最近两天,在完成工作业务之余,除了看书,自己也要开始深入的阅读经典的源码。来完善我的 iOS 源码探求 系列文章。

对源码的阅读是一个长久的学习过程,我会将业务中最常用的一些经典三方库拿出来进行学习。这一点我很敬佩 @Draveness 的精神,并向他看齐。

SDWebImage 简单介绍

SDWebImage 根据官方文档,其实就是提供了以下功能:

Asynchronous image downloader with cache support with an UIImageView category.

一个异步下载图片并且带有 UIImageView Category 的缓存库。其好用的原因还在于其简介的接口。话不多说,开始主要内容。本系列文章使用的 SDWebImage 版本为 v3.8.1

多重入口委托构造器

在使用 SD 库的时候,最常调用的方法如下:

由此,对 UIImageView 的图片一部加载完成了。进入到该方法内部,在其 .h 的文件中看到以下接口:

作为 SD 的入口函数,在 sd_setImageWithURL 方法中采用了多种参数灵活搭配的同名方法。而内部实质,都在向最后一个 sd_setImageWithURL 传入参数最多的方法进行调用处理。

在 c++ 0x 中,这种方式被广泛的使用在系统库的 class 中作为类的委托构造器(Delegate Constructor)。这样做的好处是,可以清晰的梳理函数构造逻辑,减轻代码编写量

setImageWithURL 处理流程

下面来看深入看一下上述代码注释中的 3 个要点。

  • [self sd_cancelCurrentImageLoad]

进入函数内层是以下代码:

从代码中,可以看出:SD 使用 NSDictionary 来管理满足 SDWebImageOperation 代理的实例。通过对代理实例的判断,以及使用键值查询 operation 的方式,SD 可以有效、迅速的管理所有下载任务。

  • objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

这里是使用关联对象(Associated Object)(如果这里陌生,可以查阅 浅谈Associated Objects 这篇博文),来对 UIImageView 做了一个关联值。在第二个参数上,一般是关联对象的唯一标记,在 UIImageView_WebCache.m 中使用了一个静态量地址来作为这个 key。

增加这个 url 属性便于在其他地方迅速访问。在获取时候,只需要调用 - (NSURL *)sd_imageURL 便可以直接通过关联对象迅速查询。这个 url 的访问在其他地方会有多次调用。

  • completedBlock(image, error, cacheType, url);

默认情况下,SD 会等 image 完全从网络下载完成之后,直接替换 UIImageView 中的 image 。如果想在获取图片之后,手动处理之后的所有事情,则需要设置此方法。

这个方法是将会在 SDWebImageManager.h 出现。

setAnimationImagesWithURLs 图片组

在这个 Category 中,还有对于动画组图的设置。观看源码可知,这个方法在实现上是将多个图片的 URL 打包成 array,传入 sd_setImageLoadOperation 方法来增加图片加载的 Operation 。而在打包中,相当于多次执行了 sd_setImageWithURL (其中的处理细节是一样的)。唯一不同的是,setAnimationImagesWithURLs 没有去设置关联对象。因为在展示中,我不需要对其做任何的控制,所以也就没有提供访问的快捷方法。

UIImageView+WebCache.m 源码解读总结

对于常用的 setImageWithURL 方法,可以总结成以下流程:

11uiimageviewwebcache

从最常用的 setImageWithURL 可以看出,其实 SDWebImage 的逻辑很清晰,其源码阅读起来可读性也很高。

在阅读三方库源码的同时,也可以感受到作者的代码经验所在。如同委托构造的方式,也是经验的积累总结。所以在学习代码的同时,也可以学习编码思想。

延伸阅读

cocoadocs SDWebImage

iOS 源代码分析—-SDWebImage

1 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部