SDWebImage源码解析

2017-05-10  本文已影响17人  纯情_小火鸡

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

一. 目录结构:

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


工程结构.png

二. 功能划分:

大致功能可以分为:

实现流程.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去存储到对应路径。还有一点就是对于文件的管理,当退出到后台时,会检测清楚过期文件,如果超过了最大缓存,则会清除较旧的文件直到最大缓存的一半。下图为各类的方法和内部联系。


内部结构
上一篇下一篇

猜你喜欢

热点阅读