SDWebImage小結(jié)

一、SDWebImage介紹

相信從事iOS開發(fā)的各位童鞋對(duì)于SDWebImage已經(jīng)是非常熟悉了,那么接下來我們就進(jìn)行一些對(duì)于SDWebImage的小總結(jié),了解一下SDWebImage內(nèi)部都做了一些什么操作,完成了什么牛逼的功能,可以讓眾多下載圖片的操作同時(shí)進(jìn)行。

二、SDWebImage操作步驟

在使用SDWebImage的時(shí)候,我們使用的方法一般都是- (void)sd_setImageWithURL:(NSURL *)url,或者是- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder,但是無論是哪一個(gè)方法,它們內(nèi)部都是調(diào)用的- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock方法,這個(gè)方法就是SDWebImage的核心部分。那我們就看一下這個(gè)方法內(nèi)部都做了一些什么呢

1.[self sd_cancelCurrentImageLoad];首先是調(diào)用內(nèi)部封裝好的方法,將之前該ImageView進(jìn)行的下載操作全部取消,當(dāng)然這個(gè)方法內(nèi)部還是實(shí)現(xiàn)了很多邏輯的,這個(gè)我們?cè)诤竺娴膶?shí)現(xiàn)細(xì)節(jié)里面再細(xì)說,如果你只是來做一個(gè)了解的,那么你可以只看主線劇情。

2.objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);通過runtime的方法,給每一個(gè)要進(jìn)行下載圖片操作的imageView通過一個(gè)imageURLKey來增加一個(gè)url屬性。

3.if (!(options & SDWebImageDelayPlaceholder)) {

dispatch_main_async_safe(^{

self.image = placeholder;

});?

}。先設(shè)置好占位圖片

4.接下來也就是最關(guān)鍵的部分了,當(dāng)url傳入的情況下,調(diào)用一個(gè)已經(jīng)封裝好的方法,idoperation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL),獲得一個(gè)operation,而獲得這個(gè)operation的過程,就是SDWebImage的核心部分。

第一步

判斷URL是否合法,如果不合法那么就置空。最后也就和錯(cuò)誤一起返回了。

if ([url isKindOfClass:NSString.class]) {

url = [NSURL URLWithString:(NSString *)url];

}

if (![url isKindOfClass:NSURL.class]) {

url = nil;

}

第二步

創(chuàng)建一個(gè)操作,并且查看,在已經(jīng)下載失敗的url中,是否包含這個(gè)url,通過這些標(biāo)記,來判斷下載操作是否可以正常進(jìn)行下去。然后在加鎖的情況下,將操作添加到操作數(shù)組中

__block SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new];

__weak SDWebImageCombinedOperation *weakOperation = operation;

BOOL isFailedUrl = NO;

@synchronized (self.failedURLs) {

isFailedUrl = [self.failedURLs containsObject:url];

}

if (!url || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {

dispatch_main_sync_safe(^{

NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil];

completedBlock(nil, error, SDImageCacheTypeNone, YES, url);

});

return operation;

}

@synchronized (self.runningOperations) {

[self.runningOperations addObject:operation];

}

第三步(核心部分,也是項(xiàng)目中你有可能要對(duì)SDWebImage做修改比較多的部分)

從緩存中獲取對(duì)應(yīng)下載操作的key

根據(jù)這個(gè)key是不是存在,來判斷在內(nèi)存緩存中是不是可以找到對(duì)應(yīng)的圖片

NSString *key = [self cacheKeyForURL:url];

operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) {}

- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock {

if (!doneBlock) {

return nil;

}

if (!key) {

doneBlock(nil, SDImageCacheTypeNone);

return nil;

}

NSString *newKey = [self getCacheKey:key];(這個(gè)方法一般是我們自己來自定義修改key的,比如你公司自己定義的key)

通過這個(gè)newlkey從內(nèi)存緩存中找對(duì)應(yīng)的圖片

// First check the in-memory cache...

UIImage *image = [self imageFromMemoryCacheForKey:newKey];

if (image) {

doneBlock(image, SDImageCacheTypeMemory);

return nil;

}

如果找到了,那么久執(zhí)行block,把圖片回傳,操作結(jié)束

如果找不到,那么就創(chuàng)建新的操作。如果操作被取消了,那么就直接返回

NSOperation *operation = [NSOperation new];

dispatch_async(self.ioQueue, ^{

if (operation.isCancelled) {

return;

}

如果在內(nèi)存緩存中沒有找到,并且下載操作還沒有被取消的話,那么就根據(jù)newkey從磁盤緩存中查找對(duì)應(yīng)的image。如果找到了,那么就存儲(chǔ)到內(nèi)存緩存中,當(dāng)下一次再查找相同圖片的時(shí)候就可以直接從內(nèi)存緩存中取,提高效率。

@autoreleasepool {

UIImage *diskImage = [self diskImageForKey:newKey];

if (diskImage && self.shouldCacheImagesInMemory) {

NSUInteger cost = SDCacheCostForImage(diskImage);

[self.memCache setObject:diskImage forKey:newKey cost:cost];

}

dispatch_async(dispatch_get_main_queue(), ^{

doneBlock(diskImage, SDImageCacheTypeDisk);

});

}

});

主要的過程基本上就是這樣。當(dāng)然其中還有很多的小細(xì)節(jié),比如說清除磁盤緩存啊,怎么樣保證異步下載的數(shù)據(jù)安全啊等等很多,里面也有很多我沒有仔細(xì)看的方法,在不斷的深入過程當(dāng)中我們?cè)倮^續(xù)研究,看一下其他人的代碼是怎么寫的,對(duì)于我們開闊思路還是很有幫助的。希望大家多多溝通交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 圖片下載的這些回調(diào)信息存儲(chǔ)在SDWebImageDownloader類的URLOperations屬性中,該屬性是...
    怎樣m閱讀 2,667評(píng)論 0 1
  • 技術(shù)無極限,從菜鳥開始,從源碼開始。 由于公司目前項(xiàng)目還是用OC寫的項(xiàng)目,沒有升級(jí)swift 所以暫時(shí)SDWebI...
    充滿活力的早晨閱讀 12,830評(píng)論 0 2
  • SDWebImage是一個(gè)開源的第三方庫(kù),它提供了UIImageView的一個(gè)分類,以支持從遠(yuǎn)程服務(wù)器下載并緩存圖...
    devning閱讀 476評(píng)論 0 0
  • 下載 下載管理器 SDWebImageDownLoader作為一個(gè)單例來管理圖片的下載操作。圖片的下載是放在一個(gè)N...
    wind_dy閱讀 1,658評(píng)論 0 1
  • 第一篇第二篇大概是把下載圖片緩存圖片的這個(gè)邏輯走完了,里面涉及好多類。 羅列一下 UIView+WebCache ...
    充滿活力的早晨閱讀 841評(píng)論 0 1

友情鏈接更多精彩內(nèi)容