標籤:開發 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