首先附上git地址:https://github.com/SDWebImage/SDWebImage
附上SDWebImage類圖:

附上SDWebImage步驟圖:

核心模塊三部分:
1.主要調(diào)度類:SDWebImageManager;全部操作都是圍繞它為中心;
2.主要緩存類:SDImageCache;
3.主要下載類:SDWebImageDownload;
次要:
4.和UIView相關(guān)的類,是對UIKit的擴展,只是方便我們調(diào)起Manager里面的功能類;
5.SDImageCacheConfig用于配置緩存;
問題一,SD的大概流程:
1.通過UIImageView+WebCache作為入口,有placeholderImage的情況下,先顯示占位圖;
2.通過系統(tǒng)類NSMapTable判斷當(dāng)前是否有任務(wù)在執(zhí)行;
??3.重要步驟,如圖:

問題二,內(nèi)存緩存模塊的實現(xiàn)步驟:
1.SDWebImage實現(xiàn)了磁盤,內(nèi)存雙緩存;
2.內(nèi)存緩存如何實現(xiàn)的:通過SDMemoryCache類來管理;
3.通過shouldUseWeakMemoryCache的Bool值,來判斷是否開啟內(nèi)存緩存;
4.內(nèi)存緩存有可能存在兩份,NSCache和SDMemoryCache,因為NSCache不可控;
問題三,磁盤模塊的實現(xiàn)步驟:
1.創(chuàng)建一個目錄;
2.為每一個緩存文件生成一個MD5文件名;
3.首先檢查內(nèi)存緩存,再檢查磁盤緩存,核心代碼:
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock {
if (!key) {
if (doneBlock) {
doneBlock(nil, nil, SDImageCacheTypeNone);
}
return nil;
}
id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];
if (transformer) {
// grab the transformed disk image if transformer provided
NSString *transformerKey = [transformer transformerKey];
key = SDTransformedKeyForKey(key, transformerKey);
}
// First check the in-memory cache...
//首先檢查內(nèi)存緩存…
UIImage *image = [self imageFromMemoryCacheForKey:key];
if ((options & SDImageCacheDecodeFirstFrameOnly) && image.sd_isAnimated) {
#if SD_MAC
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
#else
image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:image.imageOrientation];
#endif
}
BOOL shouldQueryMemoryOnly = (image && !(options & SDImageCacheQueryMemoryData));
if (shouldQueryMemoryOnly) {
if (doneBlock) {
doneBlock(image, nil, SDImageCacheTypeMemory);
}
return nil;
}
// Second check the disk cache...
//第二,檢查磁盤緩存…
NSOperation *operation = [NSOperation new];
// Check whether we need to synchronously query disk
// 1. in-memory cache hit & memoryDataSync
// 2. in-memory cache miss & diskDataSync
BOOL shouldQueryDiskSync = ((image && options & SDImageCacheQueryMemoryDataSync) ||
(!image && options & SDImageCacheQueryDiskDataSync));
void(^queryDiskBlock)(void) = ^{
if (operation.isCancelled) {
// do not call the completion if cancelled
return;
}
@autoreleasepool {
NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];
UIImage *diskImage;
SDImageCacheType cacheType = SDImageCacheTypeNone;
if (image) {
// the image is from in-memory cache, but need image data
diskImage = image;
cacheType = SDImageCacheTypeMemory;
} else if (diskData) {
cacheType = SDImageCacheTypeDisk;
// decode image data only if in-memory cache missed
diskImage = [self diskImageForKey:key data:diskData options:options context:context];
if (diskImage && self.config.shouldCacheImagesInMemory) {
NSUInteger cost = diskImage.sd_memoryCost;
[self.memCache setObject:diskImage forKey:key cost:cost];
}
}
if (doneBlock) {
if (shouldQueryDiskSync) {
doneBlock(diskImage, diskData, cacheType);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
doneBlock(diskImage, diskData, cacheType);
});
}
}
}
};
// Query in ioQueue to keep IO-safe
if (shouldQueryDiskSync) {
dispatch_sync(self.ioQueue, queryDiskBlock);
} else {
dispatch_async(self.ioQueue, queryDiskBlock);
}
return operation;
}
問題四,下載模塊的實現(xiàn)步驟:
1.SDWebImageDownloader實現(xiàn)了下載管理;圍繞NSURLSession實現(xiàn)的;
2.SDWebImageDownloaderOperation實現(xiàn)了生命周期管理,具體任務(wù)是它來實現(xiàn)的;
3.核心方法SDWebImageDownloader里的:
- (nullable NSOperation<SDWebImageDownloaderOperation> *)createDownloaderOperationWithUrl:(nonnull NSURL *)url
options:(SDWebImageDownloaderOptions)options
context:(nullable SDWebImageContext *)context {
...
}
4.SDWebImageDownloaderConfig里,SDWebImageDownloaderExecutionOrder枚舉,兩種情況:
/// Operation execution order
typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
/**
* Default value. All download operations will execute in queue style (first-in-first-out).
*/
SDWebImageDownloaderFIFOExecutionOrder,
/**
* All download operations will execute in stack style (last-in-first-out).
*/
SDWebImageDownloaderLIFOExecutionOrder
};
FIFOE為先進先出,LIFOE為后進先出;