SDWebImage提供了简洁的对外接口,用户只需要调用- (void)sd_setImageWithURL:(nullable NSURL *)url;
或是加上 placeholderImage
就可以实现图片的自动下载和2级缓存,那他内部是如何实现这些功能的呢?
一. 目录结构:
** 从下图中我们可以看到:大致功能结构可以分为下载类,缓存类(内存和磁盘),工具类管理类以及对于UIKit的一些类别。**
工程结构.png
二. 功能划分:
大致功能可以分为:
- 一个异步的图片加载器
- 一个异步的内存+磁盘图片缓存,并具有自动缓存过期处理功能
- 支持GIF、WebP图片
- 后台图片解压缩处理
- 确保同一个URL的图片不被下载多次
- 确保下载及缓存时,主线程不被阻塞
三. 实现原理:
上图即为实现流程图,当调用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,然后对应的监听NSURLSessionTaskDelegate和NSURLSessionDataDelegate代理方法并使用block不断的回调下载进度,最后在下载完成方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
回调完成SDWebImageDownloaderCompletedBlock
,
下载完成后,更新image的同时会将图片保存到NSCache中,如果需要保存到硬盘,会先判断图片格式,然后转成NSData,以URL的MD5作为Key去存储到对应路径。还有一点就是对于文件的管理,当退出到后台时,会检测清楚过期文件,如果超过了最大缓存,则会清除较旧的文件直到最大缓存的一半。下图为各类的方法和内部联系。
内部结构
网友评论