SDWebImage
主要功能分为两大块,一个是我们常用的网络图片下载,也就是SDWebImageDownloader
;还有一个就是图片缓存处理,也就是SDWebImageCache
。下面有个图大概显示他们的关系
- 这里箭头不是继承关系,
SDWebImageManager
只是为了方便管理的一个分类,也就是一个工具类。
接下来往下看:
sd_setImageWithURL
是我们常用的一个方法,下面我们简单解读下这个方法
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
// 取消正在进行的下载队列
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (!(options & SDWebImageDelayPlaceholder)) {
dispatch_main_async_safe(^{
self.image = placeholder;
});
}
if (url) {
// check if activityView is enabled or not
if ([self showActivityIndicatorView]) {
[self addActivityIndicator];
}
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
[wself removeActivityIndicator];
if (!wself) return;
dispatch_main_sync_safe(^{
if (!wself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
wself.image = image;
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else {
dispatch_main_async_safe(^{
[self removeActivityIndicator];
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
首先[self sd_cancelCurrentImageLoad];
取消目前正在下载的队列
上述代码中的 dispatch_main_sync_safe
与 dispatch_main_async_safe
均为宏定义, 点进去一看发现宏是
#define dispatch_main_sync_safe(block)\
if ([NSThread isMainThread]) {\
block();\
} else {\
dispatch_sync(dispatch_get_main_queue(), block);\
}
#define dispatch_main_async_safe(block)\
if ([NSThread isMainThread]) {\
block();\
} else {\
dispatch_async(dispatch_get_main_queue(), block);\
}
这个宏的作用是为了让执行block
的线程为主线程
这里主要的核心方法是downloadImageWithURL
,从名字就可看出,这是一个下载图片的方法 CMD + 鼠标左键 查看该方法,前面的if
是对传入数据的检验操作,在这里我们不用管它
id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished)
CMD + 鼠标左键 进入上述方法就会发现是用的NSMutableURLRequest
创建的网络请求,到这里是不是终于有些熟悉的感觉了,当然,这么牛逼的库肯定不是简单的使用NSURLRequest
发送网络请求,他主要是自定义封装了一个NSMutableURLRequest
类进行网络请求操作。
下一篇 主要讲讲使用和解读SDWebImage
所遇到的一些问题