SDWebImage 源码阅读 (一)

2020-02-25  本文已影响0人  Tony17
SDWebImage_logo.png

前言

SDWebImage 这个库是 OC 中最流行的网络图片加载库,它实现了图片下载,缓存,更新等和加载网络图片相关的绝大多数事情。如果项目的图片加载方面没有奇怪需求的话,这个库一定能够胜任的。之前只是粗略的看了一下这个库的实现逻辑,没有细看,今天来重新看一下。

由于本人是流程图菜鸟,并且本库使用了大量的 block,所以我打算使用分步拆解的方式来画流程图,并且我会把Block单独拿出来画一下流程图,虽然看起来会比较乱,但是好画啊。如果一个流程图示包含在其他流程图中的话,我会用颜色标出来。下面先来一个大致的总流程图:

大致流程

在调用加载网络图片的方法后,都会调用到 UIView+WebCache.h 67sd_internalSetImageWithURL: 方法。后面的步骤大致如下:

  1. 获取 operationKey 并取消当前关于这个 Key 的 operation
  2. 如果需要则显示设置占位图
  3. 重置和创建一些值、Block
  4. 查找缓存(先内存,再磁盘)
  5. 设置图片并开始下载图片(下载的原因有可能是需要更新缓存或者没有命中缓存)
  6. 设置图片并把下载的图片缓存到本地磁盘和内存中
总流程图.png

步骤分解

loadImageWithURL

这个是加载过程中最重要的步骤,主要是判断URL是否有效并查找缓存。


loadImageWithURL.png

callCompletionBlockForOperation

这个步骤其实就是在创建和调用 operation 过程中会出现需要直接返回的情况(出现错误,流程结束等), 直接调用这方法来快捷的调用 completionBlock 。内部实现就是把 Block 的调用放在一个安全的GCD里面,具体内部逻辑就是判断当前线程是否为主线程:

combinedProgressBlock

这是一个处理下载进度的 Block。这个Block在图片下载过程中会被调用到,自定义图片进度方法sd_imageProgress、图片指示器id<SDWebImageIndicator>和下载进度progressBlock会被分别调用到。

combinedProgressBlock.png

loadImageOperationBlock

这个是检查并加载本地图片资源并发起网络请求后调用的一个Block,重置imageProgressImageIndicator

这里会定义一个结束之后的 block callCompletedBlockClojure,这个 Block 会判断是否需要刷新页面,不需要的话则不会调用sd_setNeedsLayout方法。并且决定是否要调用完成的block(completedBlock)。

定义完 block 会判断一下,如果不需要设置图片的话直接调用这个 block,如果需要设置图片则会根据传入的图片信息来调用 sd_setImage:方法来设置图片,最后调用这个内部的 block 来结束。

loadImageOperationBlock.jpg

sd_setImage

这个会根据当前不同的View来调用不同的设置图片的方法,设置完之后会执行:

cacheOperationBlock

这个 Block 是在调用缓存方法之后的返回Block,里面主要处理获取缓存的结果和调用下载方法。


cacheOperationBlock.png

download & downloadBlock

这个 Block 是图片下载完成后调用的Block,图片下载部分本篇文章就不展开了,这部分其实有很多可以实现方式,本库中是使用原生的 NSURLSession 方式调用的。我们自己写的话也可以用这种方式,或者使用第三方库。以后有时间我在单独看看 NSURLSession 相关的东西。


callDownloadProcessForOperation.png

最后

这个库里面除了关于图片流程相关的这些以外,关于多平台(OSX、iPhone(iPad)、WatchOS)的适配方式其实是值得借鉴的,如果想要做一个比较稳健的通用型开源库,平台适配和判断一定是必选项。

这就是我看到的关于 SDWebImage 这个库加载图片的流程了,一定会有什么遗漏的地方,欢迎斧正。

上一篇下一篇

猜你喜欢

热点阅读