码迷,mamicode.com
首页 > Web开发 > 详细

SDWebImage源码解读(四)UIButton+WebCache

时间:2017-08-30 19:53:10      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:开发   ret   数组   run   实现   查找   ogr   按钮   ace   

UIButton+WebCache

.h 文件

1.获取当前button的图片url。

- (nullable NSURL *)sd_currentImageURL;

2.根据不同的状态获取图片url。

- (nullable NSURL *)sd_imageURLForState:(UIControlState)state;

3.设置按钮不同状态的url,然后异步加载,并且缓存。

 1 - (void)sd_setImageWithURL:(nullable NSURL *)url
 2                   forState:(UIControlState)state;
 3 
 4 - (void)sd_setImageWithURL:(nullable NSURL *)url
 5                   forState:(UIControlState)state
 6           placeholderImage:(nullable UIImage *)placeholder;
 7 
 8 - (void)sd_setImageWithURL:(nullable NSURL *)url
 9                   forState:(UIControlState)state
10           placeholderImage:(nullable UIImage *)placeholder
11                    options:(SDWebImageOptions)options;
12 
13 - (void)sd_setImageWithURL:(nullable NSURL *)url
14                   forState:(UIControlState)state
15                  completed:(nullable SDExternalCompletionBlock)completedBlock;
16 
17 - (void)sd_setImageWithURL:(nullable NSURL *)url
18                   forState:(UIControlState)state
19           placeholderImage:(nullable UIImage *)placeholder
20                  completed:(nullable SDExternalCompletionBlock)completedBlock;

这几个方法的实现全部调用这个方法实现:

1 - (void)sd_setImageWithURL:(nullable NSURL *)url
2                   forState:(UIControlState)state
3           placeholderImage:(nullable UIImage *)placeholder
4                    options:(SDWebImageOptions)options
5                  completed:(nullable SDExternalCompletionBlock)completedBlock;

4.我们再来看这几个方法:

 1 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
 2                             forState:(UIControlState)state;
 3 
 4 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
 5                             forState:(UIControlState)state
 6                     placeholderImage:(nullable UIImage *)placeholder;
 7 
 8 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
 9                             forState:(UIControlState)state
10                     placeholderImage:(nullable UIImage *)placeholder
11                              options:(SDWebImageOptions)options;
12 
13 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
14                             forState:(UIControlState)state
15                            completed:(nullable SDExternalCompletionBlock)completedBlock;
16 
17 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
18                             forState:(UIControlState)state
19                     placeholderImage:(nullable UIImage *)placeholder
20                            completed:(nullable SDExternalCompletionBlock)completedBlock;

同样,这五个方法全部是调用这个方法实现,作用是异步加载按钮背景图片,并且缓存:

1  - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
2                              forState:(UIControlState)state
3                      placeholderImage:(nullable UIImage *)placeholder
4                               options:(SDWebImageOptions)options
5                             completed:(nullable SDExternalCompletionBlock)completedBlock;

5.那么我们一鼓作气吧头文件中的方法给读完吧:

1 /**
2  * Cancel the current image download
3  */
4 - (void)sd_cancelImageLoadForState:(UIControlState)state;
5 
6 /**
7  * Cancel the current backgroundImage download
8  */
9 - (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state;

这两个方法,功能是取消当前正在下载的button的image和backgroundImage

.M(头文件看完,我们已然明白,这个类的重点在哪里。下面我们解读.m文件)

1.首先我们看两个get方法:

 1 - (nullable NSURL *)sd_currentImageURL {
 2     NSURL *url = self.imageURLStorage[@(self.state)];
 3 
 4     if (!url) {
 5         url = self.imageURLStorage[@(UIControlStateNormal)];
 6     }
 7 
 8     return url;
 9 }
10 
11 - (nullable NSURL *)sd_imageURLForState:(UIControlState)state {
12     return self.imageURLStorage[@(state)];
13 }
1 - (SDStateImageURLDictionary *)imageURLStorage {
2     SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);
3     if (!storage) {
4         storage = [NSMutableDictionary dictionary];
5         objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
6     }
7 
8     return storage;
9 }
typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary;

①看第一个获取url的方法,首先在名为 imageURLStorage 的字典中根据state查找url,如果url为nil,则默认返回 UIControlStateNormal 状态的url。第二个方法和第一个方法功能一样。

②我们看下面的字典的懒加载方法,使用了runtime,分类中不能定义属性,但是可以用runtime的方法,添加属性。

③typedef的作用,定义一个指定key和value类型的字典。咱们以后再项目开发中,也可以这么用,更加安全和有逼格。

2.好的,下面大餐来了:

 1 - (void)sd_setImageWithURL:(nullable NSURL *)url
 2                   forState:(UIControlState)state
 3           placeholderImage:(nullable UIImage *)placeholder
 4                    options:(SDWebImageOptions)options
 5                  completed:(nullable SDExternalCompletionBlock)completedBlock {
 6     if (!url) {
 7         [self.imageURLStorage removeObjectForKey:@(state)];
 8         return;
 9     }
10     
11     self.imageURLStorage[@(state)] = url;
12     
13     __weak typeof(self)weakSelf = self;
14     [self sd_internalSetImageWithURL:url
15                     placeholderImage:placeholder
16                              options:options
17                         operationKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]
18                        setImageBlock:^(UIImage *image, NSData *imageData) {
19                            [weakSelf setImage:image forState:state];
20                        }
21                             progress:nil
22                            completed:completedBlock];
23 }
 1 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
 2                             forState:(UIControlState)state
 3                     placeholderImage:(nullable UIImage *)placeholder
 4                              options:(SDWebImageOptions)options
 5                            completed:(nullable SDExternalCompletionBlock)completedBlock {
 6     if (!url) {
 7         [self.imageURLStorage removeObjectForKey:@(state)];
 8         return;
 9     }
10     
11     self.imageURLStorage[@(state)] = url;
12     
13     __weak typeof(self)weakSelf = self;
14     [self sd_internalSetImageWithURL:url
15                     placeholderImage:placeholder
16                              options:options
17                         operationKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]
18                        setImageBlock:^(UIImage *image, NSData *imageData) {
19                            [weakSelf setBackgroundImage:image forState:state];
20                        }
21                             progress:nil
22                            completed:completedBlock];
23 }

可仔细看过这两个方法的实现,不禁大失所望(纸都准备好了,你给我看这个)。原来这货也是用uiview的方法。

3.看这几个设置imageLoad和取消imageLoad的方法

 1 - (void)sd_setImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
 2     [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
 3 }
 4 
 5 - (void)sd_cancelImageLoadForState:(UIControlState)state {
 6     [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
 7 }
 8 
 9 - (void)sd_setBackgroundImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
10     [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
11 }
12 
13 - (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state {
14     [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
15 }

眼熟吧,跟上面几个方法一样,都是调用UIView+WebCacheOperation的方法来在字典中进行store operation的。

??,这个类也搞定,小总结一下UIImageView和UIButton这俩分类,方法和功能类似,都是外围看门的小弟。值得学习的点有:

①利用runtime给分类添加属性。

②使用typedef自定义指定类型的字典或者数组。

??,小伙伴们,咱们UIView+WebCache见。?

SDWebImage源码解读(四)UIButton+WebCache

标签:开发   ret   数组   run   实现   查找   ogr   按钮   ace   

原文地址:http://www.cnblogs.com/cbios/p/7454616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!