首先附上git地址:https://github.com/SDWebImage/SDWebImage
附上SDWebImage类图:
image附上SDWebImage步骤图:
image核心模块三部分:
1.主要调度类:SDWebImageManager;全部操作都是围绕它为中心;
2.主要缓存类:SDImageCache;
3.主要下载类:SDWebImageDownload;
次要:
4.和UIView相关的类,是对UIKit的扩展,只是方便我们调起Manager里面的功能类;
5.SDImageCacheConfig用于配置缓存;
问题一,SD的大概流程:
1.通过UIImageView+WebCache作为入口,有placeholderImage的情况下,先显示占位图;
2.通过系统类NSMapTable判断当前是否有任务在执行;
⭐️3.重要步骤,如图:
问题二,内存缓存模块的实现步骤:
1.SDWebImage实现了磁盘,内存双缓存;
2.内存缓存如何实现的:通过SDMemoryCache类来管理;
3.通过shouldUseWeakMemoryCache的Bool值,来判断是否开启内存缓存;
4.内存缓存有可能存在两份,NSCache和SDMemoryCache,因为NSCache不可控;
问题三,磁盘模块的实现步骤:
1.创建一个目录;
2.为每一个缓存文件生成一个MD5文件名;
3.首先检查内存缓存,再检查磁盘缓存,核心代码:
- (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...
//首先检查内存缓存…
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;
}
问题四,下载模块的实现步骤:
1.SDWebImageDownloader实现了下载管理;围绕NSURLSession实现的;
2.SDWebImageDownloaderOperation实现了生命周期管理,具体任务是它来实现的;
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为后进先出;
网友评论