SDWebImage中的- (void)sd_setImageWithURL:(NSURL *)url方法分析
来源:互联网 发布:海洋最深处 知乎 编辑:程序博客网 时间:2024/05/22 12:37
经常有面试官问到SDWebImage的请求过程。感觉有必要写下来。
查看UIImageView+WebCache.m文件:
- (void)sd_setImageWithURL:(NSURL *)url
这个方法有指定的初始化函数,所谓的指定的初始化函数,就是函数最多。下面这个方法就就是了:
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock
首先第一句是:
[self sd_cancelCurrentImageLoad];
查看UIView+WebCacheOperation.m文件:
这个是一个处理线程的文件。里面包含,线程字典初始化,线程字典设置,线程字典取消,线程字典删除。
然后是这句:
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
将url保存在imageURLKey这个key中。
然后是这句:
if (!(options & SDWebImageDelayPlaceholder)) { dispatch_main_async_safe(^{ self.image = placeholder; }); }
首先这句:
options & SDWebImageDelayPlaceholder,这个是一个位运算的与操作。翻译就是,如果options参数不是SDWebImageDelayPlaceholder,就执行以下操作。
那么,SDWebImageDelayPlaceholder是什么?看定义,默认情况下,在请求的图片正在加载的时候,占位图已加载完毕。这个标记将会延迟占位图,直到请求的图片加载完成。
看下一句:
dispatch_main_async_safe
这个是作者自己定义的。定义如下:
#define dispatch_main_async_safe(block)\ if ([NSThread isMainThread]) {\ block();\ } else {\ dispatch_async(dispatch_get_main_queue(), block);\ }
这表示,在主线程上面去执行这段函数,加载占位图。
接下来判断url是否存在,不存在发出错误信号。正确的话,执行:
if ([self showActivityIndicatorView]) { [self addActivityIndicator]; }
这句话添加加载视图。
然后是这句:
__weak __typeof(self)wself = self;
这个是避免循环引用而使用的,传递self。
看下一句,调用以下的方法:
- (id <SDWebImageOperation>)downloadImageWithURL:options:progress:completed:
看方法实现转到文件SDWebImageManager.m中:
首先是这两句:
if ([url isKindOfClass:NSString.class]) { url = [NSURL URLWithString:(NSString *)url]; }if (![url isKindOfClass:NSURL.class]) { url = nil; }
这是判断url的。
然后是这句:
__block SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new]; __weak SDWebImageCombinedOperation *weakOperation = operation;
先看一下SDWebImageCombinedOperation,这个类是实现SDWebImageOperation接口的,主要是用来发起线程和取消线程。
接下来看一下:
BOOL isFailedUrl = NO; @synchronized (self.failedURLs) { isFailedUrl = [self.failedURLs containsObject:url]; }
@synchronized这是一个互斥锁,保证此时没有其它线程对self对象进行修改。这段代码的作用是判断当前的url是否在失败url的set集合当中。
接下来这句:
if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
这句操作表示如果urlstring长度为0,或者请求失败的set集合中包含这个url,且请求的选项不是失败后重试的话,那么就返回错误代码。
然后是这句:
@synchronized (self.runningOperations) { [self.runningOperations addObject:operation]; }
将当前线程加入正在运行的队列数组中。
然后这句:
NSString *key = [self cacheKeyForURL:url];
将url转成字符串,作为Key。
接下来是这句:
operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) {
根据key到缓存中查询该图片。然后跳到SDImageCache.m该文件。
篇幅问题,直接贴图了:
- SDWebImage中的- (void)sd_setImageWithURL:(NSURL *)url方法分析
- iOS多线程-SDWebImage简单介绍 1 设置imageView的图片 (内存缓存&磁盘缓存) 1 [cell.imageView sd_setImageWithURL:[NSURL URL
- SDWebImage、NSURL
- NSURL 方法
- OC中的NSURL
- NSURL 基本方法 absoluteString
- NSURL 基本方法 absoluteString
- NSURL 基本方法
- NSURL 基本方法 absoluteString
- NSURL 基本方法
- SDWebImage [UIButton setImageWithURL:(NSURL *) forState:(UIControlState)] 的bug
- void返回值方法中的return用法
- NSURL 中的HTTP 中文乱码
- iOS基础:NSUrl常用方法
- NSURL
- NSURL
- NSURL
- NSURL
- 专治linux不服——vbox 安装增强工具 建立共享目录
- hdoj GCD 2588 (欧拉函数)
- win7 64位下安装delphi xe3及破解
- 数论之欧拉函数
- Android之路——第一步:Activity之间切换(Intent、点击事件)
- SDWebImage中的- (void)sd_setImageWithURL:(NSURL *)url方法分析
- 传智播客 Java基础 day07笔记
- 查看Android Developer文档
- C#判断操作系统类型总结
- Android在处理图片减少出现OOM的方式
- Unity3D ref的用法 out的介绍
- OPENCV学习杂录
- join解析和遍历
- Angular.JS + Require.JS + angular-async-loader 来实现异步加载 angular 模块