SDWebImage源码阅读(十八)UIImageView+WebCache

  这个分类是给 UIImageView 针对不同的情况添加 UIImage。

 .h

  下面是 UIImageView 可以使用的不同的加载图片的方式:

1 /**
2  * Set the imageView `image` with an `url`.
3  *
4  * The download is asynchronous and cached.
5  *
6  * @param url The url for the image.
7  */
8 - (void)sd_setImageWithURL:(nullable NSURL *)url;

  根据 url 异步下载和缓存 image,并把返回的 image 赋给 UIImageView。

 1 /**
 2  * Set the imageView `image` with an `url` and a placeholder.
 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  * @see sd_setImageWithURL:placeholderImage:options:
 9  */
10 - (void)sd_setImageWithURL:(nullable NSURL *)url
11           placeholderImage:(nullable UIImage *)placeholder;

  先用一个占位图片给 UIImageView 赋图,当图片下载完毕再用返回的图片把占位图替换了。

 1 /**
 2  * Set the imageView `image` with an `url`, placeholder and custom options.
 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  */
10 - (void)sd_setImageWithURL:(nullable NSURL *)url
11           placeholderImage:(nullable UIImage *)placeholder
12                    options:(SDWebImageOptions)options;

  添加一个下载选项 options。

 1 /**
 2  * Set the imageView `image` with an `url`.
 3  *
 4  * The download is asynchronous and cached.
 5  *
 6  * @param url            The url for the image.
 7  * @param completedBlock A block called when operation has been completed. This block has no return value
 8  *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 9  *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
10  *                       indicating if the image was retrieved from the local cache or from the network.
11  *                       The fourth parameter is the original image url.
12  */
13 - (void)sd_setImageWithURL:(nullable NSURL *)url
14                  completed:(nullable SDExternalCompletionBlock)completedBlock;

  只有两个参数,一个是图片的 url,一个是完成的 completedBlock。这个 block 会在图像操作完毕的时候执行。

1 typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
 1 /**
 2  * Set the imageView `image` with an `url`, placeholder.
 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 completedBlock A block called when operation has been completed. This block has no return value
 9  *                       and takes the requested UIImage as first parameter. In case of error the image parameter
10  *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
11  *                       indicating if the image was retrieved from the local cache or from the network.
12  *                       The fourth parameter is the original image url.
13  */
14 - (void)sd_setImageWithURL:(nullable NSURL *)url
15           placeholderImage:(nullable UIImage *)placeholder
16                  completed:(nullable SDExternalCompletionBlock)completedBlock;

  添加一个占位图片。

 1 /**
 2  * Set the imageView `image` with an `url`, placeholder and custom options.
 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 completedBlock A block called when operation has been completed. This block has no return value
10  *                       and takes the requested UIImage as first parameter. In case of error the image parameter
11  *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
12  *                       indicating if the image was retrieved from the local cache or from the network.
13  *                       The fourth parameter is the original image url.
14  */
15 - (void)sd_setImageWithURL:(nullable NSURL *)url
16           placeholderImage:(nullable UIImage *)placeholder
17                    options:(SDWebImageOptions)options
18                  completed:(nullable SDExternalCompletionBlock)completedBlock;

  再添加一个下载选项。

 1 /**
 2  * Set the imageView `image` with an `url`, placeholder and custom options.
 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 progressBlock  A block called while image is downloading
10  *                       @note the progress block is executed on a background queue
11  * @param completedBlock A block called when operation has been completed. This block has no return value
12  *                       and takes the requested UIImage as first parameter. In case of error the image parameter
13  *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
14  *                       indicating if the image was retrieved from the local cache or from the network.
15  *                       The fourth parameter is the original image url.
16  */
17 - (void)sd_setImageWithURL:(nullable NSURL *)url
18           placeholderImage:(nullable UIImage *)placeholder
19                    options:(SDWebImageOptions)options
20                   progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
21                  completed:(nullable SDExternalCompletionBlock)completedBlock;

  再添加一个下载进度的 block。

  这个 progressBlock 在后台队列中执行。

 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 progressBlock  A block called while image is downloading
10  *                       @note the progress block is executed on a background queue
11  * @param completedBlock A block called when operation has been completed. This block has no return value
12  *                       and takes the requested UIImage as first parameter. In case of error the image parameter
13  *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
14  *                       indicating if the image was retrieved from the local cache or from the network.
15  *                       The fourth parameter is the original image url.
16  */
17 - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url
18                                  placeholderImage:(nullable UIImage *)placeholder
19                                           options:(SDWebImageOptions)options
20                                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
21                                         completed:(nullable SDExternalCompletionBlock)completedBlock;

  获取缓存里面的图片。

 Animation of multiple images

1 /**
2  * Download an array of images and starts them in an animation loop
3  *
4  * @param arrayOfURLs An array of NSURL
5  */
6 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs;

  下载一组图像并在动画循环中启动它们。

1 - (void)sd_cancelCurrentAnimationImagesLoad;

  取消当前的图片操作。

 .m

 1 - (void)sd_setImageWithURL:(nullable NSURL *)url {
 2     [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
 3 }
 4 
 5 - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
 6     [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
 7 }
 8 
 9 - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
10     [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
11 }
12 
13 - (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
14     [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
15 }
16 
17 - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
18     [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
19 }
20 
21 - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {
22     [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
23 }

  占位图默认是 nil,下载选项默认是 0,即没有下载选项(SDWebImageOptions 是从 1 开始的),completed 默认是 nil。

 1 - (void)sd_setImageWithURL:(nullable NSURL *)url
 2           placeholderImage:(nullable UIImage *)placeholder
 3                    options:(SDWebImageOptions)options
 4                   progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
 5                  completed:(nullable SDExternalCompletionBlock)completedBlock {
 6     [self sd_internalSetImageWithURL:url
 7                     placeholderImage:placeholder
 8                              options:options
 9                         operationKey:nil
10                        setImageBlock:nil
11                             progress:progressBlock
12                            completed:completedBlock];
13 }

  依然是调用 UIView 分类 WebCache 里面的方法。operationkey 和 setImageBlock 默认是 nil。

 1 - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url
 2                                  placeholderImage:(nullable UIImage *)placeholder
 3                                           options:(SDWebImageOptions)options
 4                                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
 5                                         completed:(nullable SDExternalCompletionBlock)completedBlock {
 6     NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
 7     UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromCacheForKey:key];
 8     
 9     [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];    
10 }

  从缓存里面读取图片,做占位图片。

 1 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs {
 2     [self sd_cancelCurrentAnimationImagesLoad];
 3     __weak __typeof(self)wself = self;
 4 
 5     NSMutableArray<id<SDWebImageOperation>> *operationsArray = [[NSMutableArray alloc] init];
 6 
 7     for (NSURL *logoImageURL in arrayOfURLs) {
 8         id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
 9             if (!wself) return;
10             dispatch_main_async_safe(^{
11                 __strong UIImageView *sself = wself;
12                 [sself stopAnimating];
13                 if (sself && image) {
14                     NSMutableArray<UIImage *> *currentImages = [[sself animationImages] mutableCopy];
15                     if (!currentImages) {
16                         currentImages = [[NSMutableArray alloc] init];
17                     }
18                     [currentImages addObject:image];
19 
20                     sself.animationImages = currentImages;
21                     [sself setNeedsLayout];
22                 }
23                 [sself startAnimating];
24             });
25         }];
26         [operationsArray addObject:operation];
27     }
28 
29     [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];
30 }

  下载一组图片添加到 UIImageView 的 animationImages 里面。

1 - (void)sd_cancelCurrentAnimationImagesLoad {
2     [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
3 }

  调用 UIView 的分类 WebCacheOperation 里面的方法。取消所有的操作。

END

posted @ 2017-06-11 12:10  鳄鱼不怕牙医不怕  阅读(261)  评论(0编辑  收藏  举报