咱们开始看UIView+WebCache
.h
1 typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData);
定义一个指定参数和返回值类型的block
- (nullable NSURL *)sd_imageURL;
这也是一个get方法,获取当前视图正在请求的imageUrl
1 /** 2 * Set the imageView `image` with an `url` and optionally a placeholder image. 3 * 4 * The download is asynchronous and cached. 5 * 6 * @param url The url for the image. 7 * @param placeholder The image to be set initially, until the image request finishes. 8 * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 9 * @param operationKey A string to be used as the operation key. If nil, will use the class name 10 * @param setImageBlock Block used for custom set image code 11 * @param progressBlock A block called while image is downloading 12 * @note the progress block is executed on a background queue 13 * @param completedBlock A block called when operation has been completed. This block has no return value 14 * and takes the requested UIImage as first parameter. In case of error the image parameter 15 * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 16 * indicating if the image was retrieved from the local cache or from the network. 17 * The fourth parameter is the original image url. 18 */ 19 - (void)sd_internalSetImageWithURL:(nullable NSURL *)url 20 placeholderImage:(nullable UIImage *)placeholder 21 options:(SDWebImageOptions)options 22 operationKey:(nullable NSString *)operationKey 23 setImageBlock:(nullable SDSetImageBlock)setImageBlock 24 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 25 completed:(nullable SDExternalCompletionBlock)completedBlock;
我们来看这个UIView+WebCache对外的请求图片的接口,我们来详细解读他的参数:
①url不必说了,大家都懂。
② @param placeholder The image to be set initially, until the image request finishes.占位图,大家都懂。
③@param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.这个是下载图片时的选项,存在于SDWebImageManager类中,是一个位移枚举,那么这个枚举每一个选项的意义,我们到SDWebImageManager中再详细研究,这里我们只需要知道它的作用,它是用来操作图片下载的细节的~嗯哼~
④@param operationKey A string to be used as the operation key. If nil, will use the class name.这个是一个标识用的字符串,如果是nil,则默认是类名。
⑤@param setImageBlock Block used for custom set image code.这个block使用来自定义设置图片的block,可以为nil,block中暴露的参数有uiimage对象和imagedata。
⑥@param progressBlock A block called while image is downloading. @note the progress block is executed on a background queue这个block是在图片下载过程中调用的,而且这个block是在后台线程中执行的。block中暴露的参数有已图片下载的size和总size,以及图片url
⑦@param completedBlock A block called when operation has been completed.这个block在图片下载完成之后调用,由于这个block比较重要,我们附上代码细细观赏:
1 typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
UIimage对象,加载失败错误error,缓存类型,imageurl
- (void)sd_cancelCurrentImageLoad;
取消当前图片的下载,他也是调用UIView+WebCacheOperation的方法去缓存字典中取消队列任务。
1 #pragma mark - Activity indicator 2 3 /** 4 * Show activity UIActivityIndicatorView 5 */ 6 - (void)sd_setShowActivityIndicatorView:(BOOL)show; 7 8 /** 9 * set desired UIActivityIndicatorViewStyle 10 * 11 * @param style The style of the UIActivityIndicatorView 12 */ 13 - (void)sd_setIndicatorStyle:(UIActivityIndicatorViewStyle)style; 14 15 - (BOOL)sd_showActivityIndicatorView; 16 - (void)sd_addActivityIndicator; 17 - (void)sd_removeActivityIndicator;
这一块是添加设置移除菊花加载动画view的。这里面涉及到runtime和自动布局的知识点,我们就不讲述了。
- (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 { NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]); [self sd_cancelImageLoadOperationWithKey:validOperationKey]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); if (!(options & SDWebImageDelayPlaceholder)) { dispatch_main_async_safe(^{ [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock]; }); } if (url) { // check if activityView is enabled or not if ([self sd_showActivityIndicatorView]) { [self sd_addActivityIndicator]; } __weak __typeof(self)wself = self; id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { __strong __typeof (wself) sself = wself; [sself sd_removeActivityIndicator]; if (!sself) { return; } dispatch_main_async_safe(^{ if (!sself) { return; } if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) { completedBlock(image, error, cacheType, url); return; } else if (image) { [sself sd_setImage:image imageData:data basedOnClassOrViaCustomSetImageBlock:setImageBlock]; [sself sd_setNeedsLayout]; } else { if ((options & SDWebImageDelayPlaceholder)) { [sself sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock]; [sself sd_setNeedsLayout]; } } if (completedBlock && finished) { completedBlock(image, error, cacheType, url); } }); }]; [self sd_setImageLoadOperation:operation forKey:validOperationKey]; } else { dispatch_main_async_safe(^{ [self sd_removeActivityIndicator]; if (completedBlock) { NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; completedBlock(nil, error, SDImageCacheTypeNone, url); } }); } }
这个方法看起来很长,但是难度系数并不大,施主莫慌,且听我慢慢道来:
1.取消之前的队列
2.存储url
3.判断下载策略,如果下载策略不是SDWebImageDelayPlaceholder,那么先设置placeholder占位图。
4.如果url不为nil,判断是否显示菊花,然后是否添加菊花。
5.然后SDWebImageManager调用下载图片的方法,根据下载策略,操作completedBlock,进行图片相关的显示操作。
6.若url为nil,则completedBlock返回error。
?,目前为止,这个方法也已经差不多解析完毕,这个类是利用SDWebImageManager进行图片下载。然后用UIView+WebCacheOperation进行队列缓存操作。
下一步,我们看SDWebImageManager这个类。