SDWebImage源碼解讀(四)UIImageView+WebCache

來源:互聯網
上載者:User

標籤:ext   nload   需要   ini   ade   nal   return   取消   ring   

前言

這三個分類比較簡單,就放在一起解讀了。

本文UIImageView+WebCache

這是UIImageView的分類,旨在使用UIImageView載入圖片。

我們看具體代碼

 1 - (void)sd_setImageWithURL:(nullable NSURL *)url; 2  3 - (void)sd_setImageWithURL:(nullable NSURL *)url 4           placeholderImage:(nullable UIImage *)placeholder; 5  6 - (void)sd_setImageWithURL:(nullable NSURL *)url 7           placeholderImage:(nullable UIImage *)placeholder 8                    options:(SDWebImageOptions)options; 9 10 - (void)sd_setImageWithURL:(nullable NSURL *)url11                  completed:(nullable SDExternalCompletionBlock)completedBlock;12 13 - (void)sd_setImageWithURL:(nullable NSURL *)url14           placeholderImage:(nullable UIImage *)placeholder15                  completed:(nullable SDExternalCompletionBlock)completedBlock;16 17 - (void)sd_setImageWithURL:(nullable NSURL *)url18           placeholderImage:(nullable UIImage *)placeholder19                    options:(SDWebImageOptions)options20                  completed:(nullable SDExternalCompletionBlock)completedBlock;21 22 - (void)sd_setImageWithURL:(nullable NSURL *)url23           placeholderImage:(nullable UIImage *)placeholder24                    options:(SDWebImageOptions)options25                   progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock26                  completed:(nullable SDExternalCompletionBlock)completedBlock;27 28 - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url29                                  placeholderImage:(nullable UIImage *)placeholder30                                           options:(SDWebImageOptions)options31                                          progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock32                                         completed:(nullable SDExternalCompletionBlock)completedBlock;

跳轉到這幾個方法的具體實現,顯而易見,它們最終調用UIView+WebCache的這個方法(這個方法隨後解釋):

- (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;

有一個點稍微注意下:

劃線的三目運算子,如果問號之後的第一個參數未填寫,則預設返回條件本身。

那麼接下來,這個類還有兩個方法需要解讀:

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

根據方法聲明,我們瞭解到,這是用來載入UIImageView的幀動畫圖片數組。我們直接看方法的具體實現:

- (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs {    [self sd_cancelCurrentAnimationImagesLoad];    __weak __typeof(self)wself = self;    NSMutableArray<id<SDWebImageOperation>> *operationsArray = [[NSMutableArray alloc] init];    for (NSURL *logoImageURL in arrayOfURLs) {        id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {            if (!wself) return;            dispatch_main_async_safe(^{                __strong UIImageView *sself = wself;                [sself stopAnimating];                if (sself && image) {                    NSMutableArray<UIImage *> *currentImages = [[sself animationImages] mutableCopy];                    if (!currentImages) {                        currentImages = [[NSMutableArray alloc] init];                    }                    [currentImages addObject:image];                    sself.animationImages = currentImages;                    [sself setNeedsLayout];                }                [sself startAnimating];            });        }];        [operationsArray addObject:operation];    }    [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];}- (void)sd_cancelCurrentAnimationImagesLoad {    [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];}

我們可以看到,這個方法遍曆圖片URL數組,然後使用SDWebImageManager的方法,將每個圖片載入的操作放入operation數組中,然後調用:

    [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];

這個方法是UIView+WebCacheOperation,將所有操作用字典進行儲存。

在這個方法內部,我們看到“dispatch_main_async_safe”

1 #ifndef dispatch_main_async_safe2 #define dispatch_main_async_safe(block)3     if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {4         block();5     } else {6         dispatch_async(dispatch_get_main_queue(), block);7     }8 #endif

這是SDWebImageCompat類中的宏定義。目的是保證安全執行緒,保證block中的代碼在主線程中執行。當圖片一旦被下載,就在主線程更新UIimageview。

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

最後一個方法,是取消當前正在載入的AnimationImages操作

 

SDWebImage源碼解讀(四)UIImageView+WebCache

相關文章

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.