美文网首页
SDWebImage源码解析

SDWebImage源码解析

作者: 纯情_小火鸡 | 来源:发表于2017-05-10 16:48 被阅读17次

    SDWebImage提供了简洁的对外接口,用户只需要调用- (void)sd_setImageWithURL:(nullable NSURL *)url;或是加上 placeholderImage 就可以实现图片的自动下载和2级缓存,那他内部是如何实现这些功能的呢?

    一. 目录结构:

    ** 从下图中我们可以看到:大致功能结构可以分为下载类,缓存类(内存和磁盘),工具类管理类以及对于UIKit的一些类别。**


    工程结构.png

    二. 功能划分:

    大致功能可以分为:

    • 一个异步的图片加载器
    • 一个异步的内存+磁盘图片缓存,并具有自动缓存过期处理功能
    • 支持GIF、WebP图片
    • 后台图片解压缩处理
    • 确保同一个URL的图片不被下载多次
    • 确保下载及缓存时,主线程不被阻塞
    实现流程.png

    三. 实现原理:

    上图即为实现流程图,当调用sd_setImageWithURL ..方法的时候,实际上是调用 **UIImageView+WebCache **此类别的方法,他内部回去调用 sd_internalSetImageWithURL: ..此方法中做了不少事情,首先会根据获取的key把当前操作cancel掉:

     [self sd_cancelImageLoadOperationWithKey:validOperationKey];
    

    然后根据属性设置placeholder和activityIndicator,如果url存在接下来的SDWebImageManager就是工程最核心的地方了,他会创建一个sharedManager单例,调用loadImageWithURL ..方法获取图片,首先会根据SDWebImageCache类去以url为key到内存中去寻找图片的缓存,如果缓存未命中就会用MD5加密过的key去磁盘中继续查询, 如果找到了, 就会把磁盘中的缓存备份到内存中;当然,如果内存和磁盘都没有该图片数据,那么内部的SDWebImageDownloader对象就会调用

    - (nullable SDWebImageDownloadToken *)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock
                                           completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock
                                                   forURL:(nullable NSURL *)url
                                           createCallback:(SDWebImageDownloaderOperation *(^)())createCallback  
    

    这个方法首先会把下载的操作添加到下载和完成的回调,里面实现是调用

    - (nullable id)addHandlersForProgress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
                            completed:(nullable SDWebImageDownloaderCompletedBlock)completedBlock {
    SDCallbacksDictionary *callbacks = [NSMutableDictionary new];
    if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy];
    if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy];
    dispatch_barrier_async(self.barrierQueue, ^{
        [self.callbackBlocks addObject:callbacks];
    });
    return callbacks;
    }
    

    然后再初始化请求,创建SDWebImageDownloaderOperation 对象去请求网络,而这个SDWebImageDownloaderOperation对象是NSOperation的子类,需要添加到NSOperationQueue

    [sself.downloadQueue addOperation:operation];
    

    在重写的start方法中,启动了NSURLSessionTask,然后对应的监听NSURLSessionTaskDelegateNSURLSessionDataDelegate代理方法并使用block不断的回调下载进度,最后在下载完成方法

    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error 
    

    回调完成SDWebImageDownloaderCompletedBlock
    下载完成后,更新image的同时会将图片保存到NSCache中,如果需要保存到硬盘,会先判断图片格式,然后转成NSData,以URL的MD5作为Key去存储到对应路径。还有一点就是对于文件的管理,当退出到后台时,会检测清楚过期文件,如果超过了最大缓存,则会清除较旧的文件直到最大缓存的一半。下图为各类的方法和内部联系。


    内部结构

    相关文章

      网友评论

          本文标题:SDWebImage源码解析

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