美文网首页
SDWebImage 源码阅读 (一)

SDWebImage 源码阅读 (一)

作者: Tony17 | 来源:发表于2020-02-25 16:47 被阅读0次
    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里面,具体内部逻辑就是判断当前线程是否为主线程:

    • 如果是主线程,则直接调用 block,
    • 如果不是主线程,则使用dispatch_async(dispatch_get_main_queue(), block);调用 block

    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来调用不同的设置图片的方法,设置完之后会执行:

    • 如果有显示动画的要求的话,也会调用相关的动画代码,并在完成后调用传入的 Block
    • 如果没有显示动画的要求,则直接调用传入的 Block


      sd_setImage.png

    cacheOperationBlock

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


    cacheOperationBlock.png

    download & downloadBlock

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


    callDownloadProcessForOperation.png

    最后

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

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

    相关文章

      网友评论

          本文标题:SDWebImage 源码阅读 (一)

          本文链接:https://www.haomeiwen.com/subject/rrjgqhtx.html