Added new query cache type support, including the SDImageCache API and context option

This commit is contained in:
DreamPiggy 2020-04-01 17:01:51 +08:00
parent 0335b96114
commit fbe76bc436
7 changed files with 57 additions and 16 deletions

View File

@ -268,6 +268,19 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
*/
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock;
/**
* Asynchronously queries the cache with operation and call the completion when done.
*
* @param key The unique key used to store the wanted image. If you want transformed or thumbnail image, calculate the key with `SDTransformedKeyForKey`, `SDThumbnailedKeyForKey`, or generate the cache key from url with `cacheKeyForURL:context:`.
* @param options A mask to specify options to use for this cache query
* @param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
* @param queryCacheType Specify where to query the cache from. By default we use `.all`, which means both memory cache and disk cache. You can choose to query memory only or disk only as well. Pass `.none` is invalid and callback with nil immediatelly.
* @param doneBlock The completion block. Will not get called if the operation is cancelled
*
* @return a NSOperation instance containing the cache op
*/
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType done:(nullable SDImageCacheQueryCompletionBlock)doneBlock;
/**
* Synchronously query the memory cache.
*

View File

@ -426,12 +426,23 @@
}
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context done:(nullable SDImageCacheQueryCompletionBlock)doneBlock {
return [self queryCacheOperationForKey:key options:options context:context cacheType:SDImageCacheTypeAll done:doneBlock];
}
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType done:(nullable SDImageCacheQueryCompletionBlock)doneBlock {
if (!key) {
if (doneBlock) {
doneBlock(nil, nil, SDImageCacheTypeNone);
}
return nil;
}
// Invalid cache type
if (queryCacheType == SDImageCacheTypeNone) {
if (doneBlock) {
doneBlock(nil, nil, SDImageCacheTypeNone);
}
return nil;
}
id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];
if (transformer) {
@ -441,7 +452,10 @@
}
// First check the in-memory cache...
UIImage *image = [self imageFromMemoryCacheForKey:key];
UIImage *image;
if (queryCacheType != SDImageCacheTypeDisk) {
image = [self imageFromMemoryCacheForKey:key];
}
if (image) {
if (options & SDImageCacheDecodeFirstFrameOnly) {
@ -464,7 +478,7 @@
}
}
BOOL shouldQueryMemoryOnly = (image && !(options & SDImageCacheQueryMemoryData));
BOOL shouldQueryMemoryOnly = (queryCacheType == SDImageCacheTypeMemory) || (image && !(options & SDImageCacheQueryMemoryData));
if (shouldQueryMemoryOnly) {
if (doneBlock) {
doneBlock(image, nil, SDImageCacheTypeMemory);
@ -698,7 +712,7 @@
#pragma mark - SDImageCache
- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock {
- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock {
SDImageCacheOptions cacheOptions = 0;
if (options & SDWebImageQueryMemoryData) cacheOptions |= SDImageCacheQueryMemoryData;
if (options & SDWebImageQueryMemoryDataSync) cacheOptions |= SDImageCacheQueryMemoryDataSync;
@ -709,7 +723,7 @@
if (options & SDWebImagePreloadAllFrames) cacheOptions |= SDImageCachePreloadAllFrames;
if (options & SDWebImageMatchAnimatedImageClass) cacheOptions |= SDImageCacheMatchAnimatedImageClass;
return [self queryCacheOperationForKey:key options:cacheOptions context:context done:completionBlock];
return [self queryCacheOperationForKey:key options:cacheOptions context:context cacheType:cacheType done:completionBlock];
}
- (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(nullable NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock {

View File

@ -68,12 +68,14 @@ FOUNDATION_EXPORT UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonn
@param key The image cache key
@param options A mask to specify options to use for this query
@param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
@param cacheType Specify where to query the cache from. By default we use `.all`, which means both memory cache and disk cache. You can choose to query memory only or disk only as well. Pass `.none` is invalid and callback with nil immediatelly.
@param completionBlock The completion block. Will not get called if the operation is cancelled
@return The operation for this query
*/
- (nullable id<SDWebImageOperation>)queryImageForKey:(nullable NSString *)key
options:(SDWebImageOptions)options
context:(nullable SDWebImageContext *)context
cacheType:(SDImageCacheType)cacheType
completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock;
/**

View File

@ -84,7 +84,7 @@
#pragma mark - SDImageCache
- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)completionBlock {
- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock {
if (!key) {
return nil;
}
@ -93,30 +93,30 @@
if (count == 0) {
return nil;
} else if (count == 1) {
return [caches.firstObject queryImageForKey:key options:options context:context completion:completionBlock];
return [caches.firstObject queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock];
}
switch (self.queryOperationPolicy) {
case SDImageCachesManagerOperationPolicyHighestOnly: {
id<SDImageCache> cache = caches.lastObject;
return [cache queryImageForKey:key options:options context:context completion:completionBlock];
return [cache queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock];
}
break;
case SDImageCachesManagerOperationPolicyLowestOnly: {
id<SDImageCache> cache = caches.firstObject;
return [cache queryImageForKey:key options:options context:context completion:completionBlock];
return [cache queryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock];
}
break;
case SDImageCachesManagerOperationPolicyConcurrent: {
SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];
[operation beginWithTotalCount:caches.count];
[self concurrentQueryImageForKey:key options:options context:context completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];
[self concurrentQueryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];
return operation;
}
break;
case SDImageCachesManagerOperationPolicySerial: {
SDImageCachesManagerOperation *operation = [SDImageCachesManagerOperation new];
[operation beginWithTotalCount:caches.count];
[self serialQueryImageForKey:key options:options context:context completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];
[self serialQueryImageForKey:key options:options context:context cacheType:cacheType completion:completionBlock enumerator:caches.reverseObjectEnumerator operation:operation];
return operation;
}
break;
@ -279,11 +279,11 @@
#pragma mark - Concurrent Operation
- (void)concurrentQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {
- (void)concurrentQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {
NSParameterAssert(enumerator);
NSParameterAssert(operation);
for (id<SDImageCache> cache in enumerator) {
[cache queryImageForKey:key options:options context:context completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {
[cache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {
if (operation.isCancelled) {
// Cancelled
return;
@ -422,7 +422,7 @@
#pragma mark - Serial Operation
- (void)serialQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {
- (void)serialQueryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context cacheType:(SDImageCacheType)queryCacheType completion:(SDImageCacheQueryCompletionBlock)completionBlock enumerator:(NSEnumerator<id<SDImageCache>> *)enumerator operation:(SDImageCachesManagerOperation *)operation {
NSParameterAssert(enumerator);
NSParameterAssert(operation);
id<SDImageCache> cache = enumerator.nextObject;
@ -435,7 +435,7 @@
return;
}
@weakify(self);
[cache queryImageForKey:key options:options context:context completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {
[cache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType) {
@strongify(self);
if (operation.isCancelled) {
// Cancelled
@ -455,7 +455,7 @@
return;
}
// Next
[self serialQueryImageForKey:key options:options context:context completion:completionBlock enumerator:enumerator operation:operation];
[self serialQueryImageForKey:key options:options context:context cacheType:queryCacheType completion:completionBlock enumerator:enumerator operation:operation];
}];
}

View File

@ -259,6 +259,12 @@ FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageP
*/
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageThumbnailPixelSize;
/**
A SDImageCacheType raw value which specify the source of cache to query. For example, you can query memory only, query disk only, or query from both memory and disk cache.
If not provide or the value is invalid, we will use `SDImageCacheTypeAll`. (NSNumber)
*/
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextQueryCacheType;
/**
A SDImageCacheType raw value which specify the store cache type when the image has just been downloaded and will be stored to the cache. Specify `SDImageCacheTypeNone` to disable cache storage; `SDImageCacheTypeDisk` to store in disk cache only; `SDImageCacheTypeMemory` to store in memory only. And `SDImageCacheTypeAll` to store in both memory cache and disk cache.
If you use image transformer feature, this actually apply for the transformed image, but not the original image itself. Use `SDWebImageContextOriginalStoreCacheType` if you want to control the original image's store cache type at the same time.

View File

@ -127,6 +127,7 @@ SDWebImageContextOption const SDWebImageContextImageTransformer = @"imageTransfo
SDWebImageContextOption const SDWebImageContextImageScaleFactor = @"imageScaleFactor";
SDWebImageContextOption const SDWebImageContextImagePreserveAspectRatio = @"imagePreserveAspectRatio";
SDWebImageContextOption const SDWebImageContextImageThumbnailPixelSize = @"imageThumbnailPixelSize";
SDWebImageContextOption const SDWebImageContextQueryCacheType = @"queryCacheType";
SDWebImageContextOption const SDWebImageContextStoreCacheType = @"storeCacheType";
SDWebImageContextOption const SDWebImageContextOriginalStoreCacheType = @"originalStoreCacheType";
SDWebImageContextOption const SDWebImageContextAnimatedImageClass = @"animatedImageClass";

View File

@ -220,10 +220,15 @@ static id<SDImageLoader> _defaultImageLoader;
}
// Check whether we should query cache
BOOL shouldQueryCache = !SD_OPTIONS_CONTAINS(options, SDWebImageFromLoaderOnly);
// Get the query cache type
SDImageCacheType queryCacheType = SDImageCacheTypeAll;
if (context[SDWebImageContextQueryCacheType]) {
queryCacheType = [context[SDWebImageContextQueryCacheType] integerValue];
}
if (shouldQueryCache) {
NSString *key = [self cacheKeyForURL:url context:context];
@weakify(operation);
operation.cacheOperation = [imageCache queryImageForKey:key options:options context:context completion:^(UIImage * _Nullable cachedImage, NSData * _Nullable cachedData, SDImageCacheType cacheType) {
operation.cacheOperation = [imageCache queryImageForKey:key options:options context:context cacheType:queryCacheType completion:^(UIImage * _Nullable cachedImage, NSData * _Nullable cachedData, SDImageCacheType cacheType) {
@strongify(operation);
if (!operation || operation.isCancelled) {
// Image combined operation cancelled by user