在jianshu.com/p/077638fb6756中简要介绍了SDWebImageManage.h中定义的各个方法和属性的含义,这篇开始介绍相应的方法的具体实现。
首先,SDWebImageManager中使用的核心方法是
- (id <SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url
options:(SDWebImageOptions)options
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDInternalCompletionBlock)completedBlock
我们就从这里开始看起,这个方法是SDWebImage暴露给我们的方法,在使用的过程中只需要调用这个方法即可,几乎所有的实现都是在这个方法中实现的。
//这个是判断的下载失败时的处理,当url为空或者options不是SDWebImageRetryFailed(这个前面有写,对于下载失败的链接会重新请求)或者url是被标记为失败的url时,调用相应的失败的处理方法
if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil] url:url];
return operation;
}
看到一个比较有意思的代码
image.png
上面图片中是关于block中self的弱引用的写法,这个值得学习一下
//判断是否需要从网络上下载图片
BOOL shouldDownload = (!(options & SDWebImageFromCacheOnly))
&& (!cachedImage || options & SDWebImageRefreshCached)
&& (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url]);
if (shouldDownload) {
if (cachedImage && options & SDWebImageRefreshCached) {
//如果在内存中发现了图片,但是options是SDWebImageRefreshCached即需要重新刷新图片
[self callCompletionBlockForOperation:strongOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];
}
下面开始下载,定义了下载的枚举类,每个的含义为:
//将下载置于低队列优先级和低任务优先级
SDWebImageDownloaderLowPriority = 1 << 0,
//此标志支持渐进式下载,图像在下载过程中会像浏览器一样逐步显示。
SDWebImageDownloaderProgressiveDownload = 1 << 1,
//默认情况下,请求不允许使用NSURLFlag,这个标志表示允许使用
SDWebImageDownloaderUseNSURLCache = 1 << 2,
//如果从NSURLCache读取图像,则调用nil image/imageData完成块
SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
//app进入后台仍然继续下载
SDWebImageDownloaderContinueInBackground = 1 << 4,
//通过NSMutableURLRequest处理存储在NSHTTPCookieStore中的cookie
SDWebImageDownloaderHandleCookies = 1 << 5,
//启用允许不受信任的SSL证书。用于测试目的。在生产中小心使用
SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
//将下载置于高队列优先级和高任务优先级
SDWebImageDownloaderHighPriority = 1 << 7,
//改变下载图片的大小
SDWebImageDownloaderScaleDownLargeImages = 1 << 8,
downloaderOptions获取到对应的值后,
if (cachedImage && options & SDWebImageRefreshCached) {
//如果图像已经缓存但强制刷新,则强制渐进关闭
downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
//忽略从NSURLCache读取的图像,如果图像被缓存,强制刷新
downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
}
整体看完这个方法,总体主要就是三个方面
if (shouldDownload) {
//这一部分是最复杂的,应该通过网络下载,这里面就是下载图片以及相应的磁盘和内存存储和更新
if (cachedImage && options & SDWebImageRefreshCached) {
//应该通过网络请求下载,缓存中有图片,但是需要刷新(重新下载)
}
} else if (cacheImage) {
//如果缓存中有相应的图片,则直接使用
} else {
//如果缓存中没有相应的图片但是也不允许通过网络请求下载的话的处理
}
SDWebImage源码阅读(一)
SDWebImage源码阅读(二)
SDWebImage源码阅读(三)
SDWebImage源码阅读(四)
SDWebImage源码阅读(五)
SDWebImage源码阅读(六)
网友评论