SDWebImage源碼解讀(四)UIButton+WebCache

來源:互聯網
上載者:User

標籤:開發   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)state10           placeholderImage:(nullable UIImage *)placeholder11                    options:(SDWebImageOptions)options;12 13 - (void)sd_setImageWithURL:(nullable NSURL *)url14                   forState:(UIControlState)state15                  completed:(nullable SDExternalCompletionBlock)completedBlock;16 17 - (void)sd_setImageWithURL:(nullable NSURL *)url18                   forState:(UIControlState)state19           placeholderImage:(nullable UIImage *)placeholder20                  completed:(nullable SDExternalCompletionBlock)completedBlock;

這幾個方法的實現全部調用這個方法實現:

1 - (void)sd_setImageWithURL:(nullable NSURL *)url2                   forState:(UIControlState)state3           placeholderImage:(nullable UIImage *)placeholder4                    options:(SDWebImageOptions)options5                  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)state10                     placeholderImage:(nullable UIImage *)placeholder11                              options:(SDWebImageOptions)options;12 13 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url14                             forState:(UIControlState)state15                            completed:(nullable SDExternalCompletionBlock)completedBlock;16 17 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url18                             forState:(UIControlState)state19                     placeholderImage:(nullable UIImage *)placeholder20                            completed:(nullable SDExternalCompletionBlock)completedBlock;

同樣,這五個方法全部是調用這個方法實現,作用是非同步載入按鈕背景圖片,並且緩衝:

1  - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url2                              forState:(UIControlState)state3                      placeholderImage:(nullable UIImage *)placeholder4                               options:(SDWebImageOptions)options5                             completed:(nullable SDExternalCompletionBlock)completedBlock;

5.那麼我們一鼓作氣吧標頭檔中的方法給讀完吧:

1 /**2  * Cancel the current image download3  */4 - (void)sd_cancelImageLoadForState:(UIControlState)state;5 6 /**7  * Cancel the current backgroundImage download8  */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:url15                     placeholderImage:placeholder16                              options:options17                         operationKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]18                        setImageBlock:^(UIImage *image, NSData *imageData) {19                            [weakSelf setImage:image forState:state];20                        }21                             progress:nil22                            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:url15                     placeholderImage:placeholder16                              options:options17                         operationKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]18                        setImageBlock:^(UIImage *image, NSData *imageData) {19                            [weakSelf setBackgroundImage:image forState:state];20                        }21                             progress:nil22                            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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: