对源码的阅读是一个长久的学习过程,我会将业务中最常用的一些经典三方库拿出来进行学习。这一点我很敬佩 @Draveness 的精神,并向他看齐。
SDWebImage 简单介绍
SDWebImage 根据官方文档,其实就是提供了以下功能:
Asynchronous image downloader with cache support with an UIImageView category.
一个异步下载图片并且带有 UIImageView
Category 的缓存库。其好用的原因还在于其简介的接口。话不多说,开始主要内容。本系列文章使用的 SDWebImage 版本为 v3.8.1
。
多重入口委托构造器
在使用 SD 库的时候,最常调用的方法如下:
1 2 |
[self.imageView sd_setImageWithURL:[NSURL URLWithString:@"url"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; |
由此,对 UIImageView
的图片一部加载完成了。进入到该方法内部,在其 .h
的文件中看到以下接口:
1 2 3 4 5 |
- (void)sd_setImageWithURL:(NSURL *)url; - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; ... - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; |
作为 SD 的入口函数,在 sd_setImageWithURL 方法中采用了多种参数灵活搭配的同名方法。而内部实质,都在向最后一个 sd_setImageWithURL 传入参数最多的方法进行调用处理。
在 c++ 0x 中,这种方式被广泛的使用在系统库的 class 中作为类的委托构造器(Delegate Constructor)。这样做的好处是,可以清晰的梳理函数构造逻辑,减轻代码编写量。
setImageWithURL 处理流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
// 委托构造器最高级入口 - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { // 【要点 1】取消该 UIImageView 的下载队列 [self sd_cancelCurrentImageLoad]; // 【要点 2】对应的 UIImageView 增加一个对应的 url 属性 objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); // 根据参数条件,是一个 optional 执行块 // 在未发送请求过去网络图片之前,增加 placeHolder // 如果有 delay 延迟标记 if (!(options & SDWebImageDelayPlaceholder)) { // 创建主线程异步队列来更新 UI dispatch_main_async_safe(^{ self.image = placeholder; }); } // 判断 url 是否为空 if (url) { // 是否展示 ActivityIndicator if ([self showActivityIndicatorView]) { [self addActivityIndicator]; } // 防止 block 的 retain cycle,进行弱引用转换 __weak __typeof(self)wself = self; // 使用图片 download 方法,并完成 callback 回调 id SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { // 停止 ActivityIndicator 转动 [wself removeActivityIndicator]; if (!wselfremoveActivityIndicator]; if (!wselfȑ很敬佩 @Draveness 的精神,并向他看齐。
SDWebImage 简单介绍SDWebImage 根据官方文档,其实就是提供了以下功能:
一个异步下载图片并且带有 多重入口委托构造器在使用 SD 库的时候,最常调用的方法如下:
由此,对
作为 SD 的入口函数,在 sd_setImageWithURL 方法中采用了多种参数灵活搭配的同名方法。而内部实质,都在向最后一个 sd_setImageWithURL 传入参数最多的方法进行调用处理。 在 c++ 0x 中,这种方式被广泛的使用在系统库的 class 中作为类的委托构造器(Delegate Constructor)。这样做的好处是,可以清晰的梳理函数构造逻辑,减轻代码编写量。 setImageWithURL 处理流程
|