美文网首页
SDWebImage源码解析

SDWebImage源码解析

作者: HJXu | 来源:发表于2017-03-10 17:06 被阅读168次

    说白了,这个框架是一个异步下载图片并且支持缓存的 UIImageView 分类
    原理图如下:


    01.png

    最常使用的是这个方法

    [self.imageView sd_setImageWithURL:[NSURL URLWithString:@"url"]
                      placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
    

    首先我们来以UIImageView+WebCache中- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;这个方法为入口研究SDWebImage是如何工作的.
    当我们进入到.m实现文件的时候如下

    02.png
    发现这个方法唯一的作用就是调用了另一个方法
    [self sd_setImageWithURL:placeholderImage:options:progress:completed:]
    

    其实仔细看看暴露给我们使用的方法后,不难看出,最终都会调用这个方法,只是根据需要传入的参数不同而已,无疑这是UIImageView+WebCache中的核心方法
    这个方法具体实现代码比较多,大家点击头文件都可以看到

    操作管理

    方法的第一行代码是

    [self sd_cancelCurrentImageLoad];
    

    这是整个框架管理操作队列的方法,写这个方法是取消当前正在进行中的下载(实际上没有下载),防止与即将进行的操作发生冲突.会调用:

    [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"]```
    ###占位图片
    

    if (!(options & SDWebImageDelayPlaceholder)) {
    self.image = placeholder;
    }

    默认情况下options == 0,那么会为当前的UIImageView添加一个临时的image,也就是占位图.
    ####获取图片
    接下来会检测传入的url是否为空,非空全局SDWebImageView会调用以下方法获取图片
    

    [SDWebImageManager.sharedManager downloadImageWithURL:options:progress:completed:]

    下载完后会调用```(SDWebImageCompletionWithFinishedBlock)completedBlock```为UIImageView.image赋值,添加上最终所需要的图片
    

    dispatch_main_sync_safe(^{
    if (!wself) return;
    if (image) {
    wself.image = image;
    [wself setNeedsLayout];
    } else {
    if ((options & SDWebImageDelayPlaceholder)) {
    wself.image = placeholder;
    [wself setNeedsLayout];
    }
    }
    if (completedBlock && finished) {
    completedBlock(image, error, cacheType, url);
    }
    });

    接下来分析SDWebImageManager中的方法
    

    [SDWebImageManager.sharedManager downloadImageWithURL:options:progress:completed:]

    ####SDWebImageManager
    这个类是用来处理异步下载和图片缓存的类,
    获取图片的过程有大体上分为两部分, 它首先会在 SDWebImageCache 中寻找图片是否有对应的缓存, 它会以 url 作为数据的索引先在内存中寻找是否有对应的缓存, 如果缓存未命中就会在磁盘中利用 MD5 处理过的 key 来继续查询对应的数据, 如果找到了, 就会把磁盘中的缓存备份到内存中.
    
    然而, 假设我们在内存和磁盘缓存中都没有命中, 那么 manager 就会调用它持有的一个 SDWebImageDownloader 对象的方法 downloadImageWithURL:... 来下载图片, 这个方法会在执行的过程中调用另一个方法 addProgressCallback:andCompletedBlock:forURL:createCallback: 来存储下载过程中和下载完成的回调, 当回调块是第一次添加的时候, 方法会实例化一个 NSMutableURLRequest 和 SDWebImageDownloaderOperation, 并将后者加入 downloader 持有的下载队列开始图片的异步下载.
    而在图片下载完成之后, 就会在主线程设置 image 属性, 完成整个图像的异步下载和配置.
    ####总结
    整个框架的图片加载过程其实很符合我们常人的逻辑
    查看缓存:
    a)查看内存中(程序可能已经加载过这个图片)是否有缓存,如果有就返回图片设置图片;没有就查看磁盘缓存,有就返回图片并设置
    b)内存和磁盘中都没有缓存,网络异步下载图片,加入磁盘缓存和内存缓存,设置图片

    相关文章

      网友评论

          本文标题:SDWebImage源码解析

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