前言
这三个分类比较简单,就放在一起解读了。
正文
UIImageView+WebCache
这是UIImageView的分类,旨在使用UIImageView加载图片。
我们看具体代码
1 - (void)sd_setImageWithURL:(nullable NSURL *)url; 2 ?3 - (void)sd_setImageWithURL:(nullable NSURL *)url 4 ??????????placeholderImage:(nullable UIImage *)placeholder; 5 ?6 - (void)sd_setImageWithURL:(nullable NSURL *)url 7 ??????????placeholderImage:(nullable UIImage *)placeholder 8 ???????????????????options:(SDWebImageOptions)options; 9 10 - (void)sd_setImageWithURL:(nullable NSURL *)url11 ?????????????????completed:(nullable SDExternalCompletionBlock)completedBlock;12 13 - (void)sd_setImageWithURL:(nullable NSURL *)url14 ??????????placeholderImage:(nullable UIImage *)placeholder15 ?????????????????completed:(nullable SDExternalCompletionBlock)completedBlock;16 17 - (void)sd_setImageWithURL:(nullable NSURL *)url18 ??????????placeholderImage:(nullable UIImage *)placeholder19 ???????????????????options:(SDWebImageOptions)options20 ?????????????????completed:(nullable SDExternalCompletionBlock)completedBlock;21 22 - (void)sd_setImageWithURL:(nullable NSURL *)url23 ??????????placeholderImage:(nullable UIImage *)placeholder24 ???????????????????options:(SDWebImageOptions)options25 ??????????????????progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock26 ?????????????????completed:(nullable SDExternalCompletionBlock)completedBlock;27 28 - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url29 ?????????????????????????????????placeholderImage:(nullable UIImage *)placeholder30 ??????????????????????????????????????????options:(SDWebImageOptions)options31 ?????????????????????????????????????????progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock32 ????????????????????????????????????????completed:(nullable SDExternalCompletionBlock)completedBlock;
跳转到这几个方法的具体实现,显而易见,它们最终调用UIView+WebCache的这个方法(这个方法随后解释):
- (void)sd_internalSetImageWithURL:(nullable NSURL *)url ?????????????????placeholderImage:(nullable UIImage *)placeholder ??????????????????????????options:(SDWebImageOptions)options ?????????????????????operationKey:(nullable NSString *)operationKey ????????????????????setImageBlock:(nullable SDSetImageBlock)setImageBlock ?????????????????????????progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock ????????????????????????completed:(nullable SDExternalCompletionBlock)completedBlock;
有一个点稍微注意下:
划线的三目运算符,如果问号之后的第一个参数未填写,则默认返回条件本身。
那么接下来,这个类还有两个方法需要解读:
1 /**2 ?* Download an array of images and starts them in an animation loop3 ?*4 ?* @param arrayOfURLs An array of NSURL5 ?*/6 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs;7 8 - (void)sd_cancelCurrentAnimationImagesLoad;
根据方法声明,我们了解到,这是用来加载UIImageView的帧动画图片数组。我们直接看方法的具体实现:
- (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs { ???[self sd_cancelCurrentAnimationImagesLoad]; ???__weak __typeof(self)wself = self; ???NSMutableArray<id<SDWebImageOperation>> *operationsArray = [[NSMutableArray alloc] init]; ???for (NSURL *logoImageURL in arrayOfURLs) { ???????id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { ???????????if (!wself) return; ???????????dispatch_main_async_safe(^{ ???????????????__strong UIImageView *sself = wself; ???????????????[sself stopAnimating]; ???????????????if (sself && image) { ???????????????????NSMutableArray<UIImage *> *currentImages = [[sself animationImages] mutableCopy]; ???????????????????if (!currentImages) { ???????????????????????currentImages = [[NSMutableArray alloc] init]; ???????????????????} ???????????????????[currentImages addObject:image]; ???????????????????sself.animationImages = currentImages; ???????????????????[sself setNeedsLayout]; ???????????????} ???????????????[sself startAnimating]; ???????????}); ???????}]; ???????[operationsArray addObject:operation]; ???} ???[self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];}- (void)sd_cancelCurrentAnimationImagesLoad { ???[self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];}
我们可以看到,这个方法遍历图片URL数组,然后使用SDWebImageManager的方法,将每个图片加载的操作放入operation数组中,然后调用:
[self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];
这个方法是UIView+WebCacheOperation,将所有操作用字典进行存储。
在这个方法内部,我们看到“dispatch_main_async_safe”
1 #ifndef dispatch_main_async_safe2 #define dispatch_main_async_safe(block)3 ????if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {4 ????????block();5 ????} else {6 ????????dispatch_async(dispatch_get_main_queue(), block);7 ????}8 #endif
这是SDWebImageCompat类中的宏定义。目的是保证线程安全,保证block中的代码在主线程中执行。当图片一旦被下载,就在主线程更新UIimageview。
- (void)sd_cancelCurrentAnimationImagesLoad { ???[self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];}
最后一个方法,是取消当前正在加载的AnimationImages操作
SDWebImage源码解读(四)UIImageView+WebCache
原文地址:http://www.cnblogs.com/cbios/p/7452346.html