Refactory the current thumbnail && transformer about cache key. Developer should have the API to calcualte the cache key from thumbnail or transformer, not hard-coded.

This commit is contained in:
DreamPiggy 2020-03-31 18:47:51 +08:00
parent 51dee05acf
commit 1dc70b8430
7 changed files with 38 additions and 20 deletions

View File

@ -247,7 +247,7 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
/** /**
* Operation that queries the cache asynchronously and call the completion when done. * Operation that queries the cache asynchronously and call the completion when done.
* *
* @param key The unique key used to store the wanted image * @param key The unique key used to store the wanted image. If you need transformer's image, calculate the key with `SDTransformedKeyForKey` or generate the cache key from url with `cacheKeyForURL:context:`.
* @param doneBlock The completion block. Will not get called if the operation is cancelled * @param doneBlock The completion block. Will not get called if the operation is cancelled
* *
* @return a NSOperation instance containing the cache op * @return a NSOperation instance containing the cache op
@ -257,7 +257,7 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
/** /**
* Asynchronously queries the cache with operation and call the completion when done. * Asynchronously queries the cache with operation and call the completion when done.
* *
* @param key The unique key used to store the wanted image * @param key The unique key used to store the wanted image. If you need transformer's image, calculate the key with `SDTransformedKeyForKey` or generate the cache key from url with `cacheKeyForURL:context:`.
* @param options A mask to specify options to use for this cache query * @param options A mask to specify options to use for this cache query
* @param doneBlock The completion block. Will not get called if the operation is cancelled * @param doneBlock The completion block. Will not get called if the operation is cancelled
* *
@ -268,7 +268,7 @@ typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
/** /**
* Asynchronously queries the cache with operation and call the completion when done. * Asynchronously queries the cache with operation and call the completion when done.
* *
* @param key The unique key used to store the wanted image * @param key The unique key used to store the wanted image. If you need transformer's image, calculate the key with `SDTransformedKeyForKey` or generate the cache key from url with `cacheKeyForURL:context:`.
* @param options A mask to specify options to use for this cache query * @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 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 doneBlock The completion block. Will not get called if the operation is cancelled * @param doneBlock The completion block. Will not get called if the operation is cancelled

View File

@ -9,7 +9,6 @@
#import "SDImageCache.h" #import "SDImageCache.h"
#import "NSImage+Compatibility.h" #import "NSImage+Compatibility.h"
#import "SDImageCodersManager.h" #import "SDImageCodersManager.h"
#import "SDImageTransformer.h"
#import "SDImageCoderHelper.h" #import "SDImageCoderHelper.h"
#import "SDAnimatedImage.h" #import "SDAnimatedImage.h"
#import "UIImage+MemoryCacheCost.h" #import "UIImage+MemoryCacheCost.h"
@ -455,13 +454,6 @@
return nil; 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... // First check the in-memory cache...
UIImage *image; UIImage *image;
if (queryCacheType != SDImageCacheTypeDisk) { if (queryCacheType != SDImageCacheTypeDisk) {

View File

@ -61,7 +61,7 @@ FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeCompressio
But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data inforamtion only. But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data inforamtion only.
See `SDWebImageContext` for more detailed information. See `SDWebImageContext` for more detailed information.
*/ */
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderWebImageContext; FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderWebImageContext API_DEPRECATED("The coder component will be seperated from Core subspec in the future. Update your code to not rely on this context option.", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));;
#pragma mark - Coder #pragma mark - Coder
/** /**

View File

@ -18,6 +18,15 @@
*/ */
FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey); FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey);
/**
Return the thumbnailed cache key which applied with specify thumbnailSize and preserveAspectRatio control.
@param key The original cache key
@param thumbnailPixelSize The thumbnail pixel size
@param preserveAspectRatio The preserve aspect ratio option
@return The thumbnailed cache key
*/
FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio);
/** /**
A transformer protocol to transform the image load from cache or from download. A transformer protocol to transform the image load from cache or from download.
You can provide transformer to cache and manager (Through the `transformer` property or context option `SDWebImageContextImageTransformer`). You can provide transformer to cache and manager (Through the `transformer` property or context option `SDWebImageContextImageTransformer`).
@ -38,10 +47,10 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
Transform the image to another image. Transform the image to another image.
@param image The image to be transformed @param image The image to be transformed
@param key The cache key associated to the image @param key The cache key associated to the image. This arg is a hint for image source, not always useful and should be nullable. In the future we will remove this arg.
@return The transformed image, or nil if transform failed @return The transformed image, or nil if transform failed
*/ */
- (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key; - (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key API_DEPRECATED("The key arg will be removed in the future. Update your code and don't rely on that.", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));
@end @end

View File

@ -38,6 +38,11 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
} }
} }
NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio) {
NSString *thumbnailKey = [NSString stringWithFormat:@"Thumbnail({%f,%f},%d)", thumbnailPixelSize.width, thumbnailPixelSize.height, preserveAspectRatio];
return SDTransformedKeyForKey(key, thumbnailKey);
}
@interface SDImagePipelineTransformer () @interface SDImagePipelineTransformer ()
@property (nonatomic, copy, readwrite, nonnull) NSArray<id<SDImageTransformer>> *transformers; @property (nonatomic, copy, readwrite, nonnull) NSArray<id<SDImageTransformer>> *transformers;

View File

@ -266,4 +266,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
*/ */
- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url; - (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url;
/**
* Return the cache key for a given URL and context option.
* Some option like `.thumbnailPixelSize` and `imageTransformer` will effect the generated cache key, using this if you have those context associated.
*/
- (nullable NSString *)cacheKeyForURL:(nullable NSURL *)url context:(nullable SDWebImageContext *)context;
@end @end

View File

@ -114,6 +114,7 @@ static id<SDImageLoader> _defaultImageLoader;
} else { } else {
key = url.absoluteString; key = url.absoluteString;
} }
// Thumbnail Key Appending // Thumbnail Key Appending
NSValue *thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize]; NSValue *thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];
if (thumbnailSizeValue != nil) { if (thumbnailSizeValue != nil) {
@ -123,14 +124,21 @@ static id<SDImageLoader> _defaultImageLoader;
#else #else
thumbnailSize = thumbnailSizeValue.CGSizeValue; thumbnailSize = thumbnailSizeValue.CGSizeValue;
#endif #endif
BOOL preserveAspectRatio = YES; BOOL preserveAspectRatio = YES;
NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio]; NSNumber *preserveAspectRatioValue = context[SDWebImageContextImagePreserveAspectRatio];
if (preserveAspectRatioValue != nil) { if (preserveAspectRatioValue != nil) {
preserveAspectRatio = preserveAspectRatioValue.boolValue; preserveAspectRatio = preserveAspectRatioValue.boolValue;
} }
NSString *transformerKey = [NSString stringWithFormat:@"Thumbnail({%f,%f},%d)", thumbnailSize.width, thumbnailSize.height, preserveAspectRatio]; key = SDThumbnailedKeyForKey(key, thumbnailSize, preserveAspectRatio);
key = SDTransformedKeyForKey(key, transformerKey); }
// Transformer Key Appending
id<SDImageTransformer> transformer = self.transformer;
if (context[SDWebImageContextImageTransformer]) {
transformer = context[SDWebImageContextImageTransformer];
}
if (transformer) {
key = SDTransformedKeyForKey(key, transformer.transformerKey);
} }
return key; return key;
@ -409,8 +417,6 @@ static id<SDImageLoader> _defaultImageLoader;
@autoreleasepool { @autoreleasepool {
UIImage *transformedImage = [transformer transformedImageWithImage:originalImage forKey:key]; UIImage *transformedImage = [transformer transformedImageWithImage:originalImage forKey:key];
if (transformedImage && finished) { if (transformedImage && finished) {
NSString *transformerKey = [transformer transformerKey];
NSString *cacheKey = SDTransformedKeyForKey(key, transformerKey);
BOOL imageWasTransformed = ![transformedImage isEqual:originalImage]; BOOL imageWasTransformed = ![transformedImage isEqual:originalImage];
NSData *cacheData; NSData *cacheData;
// pass nil if the image was transformed, so we can recalculate the data from the image // pass nil if the image was transformed, so we can recalculate the data from the image
@ -421,7 +427,7 @@ static id<SDImageLoader> _defaultImageLoader;
} }
// keep the original image format and extended data // keep the original image format and extended data
SDImageCopyAssociatedObject(originalImage, transformedImage); SDImageCopyAssociatedObject(originalImage, transformedImage);
[self storeImage:transformedImage imageData:cacheData forKey:cacheKey cacheType:storeCacheType options:options context:context completion:^{ [self storeImage:transformedImage imageData:cacheData forKey:key cacheType:storeCacheType options:options context:context completion:^{
[self callCompletionBlockForOperation:operation completion:completedBlock image:transformedImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url]; [self callCompletionBlockForOperation:operation completion:completedBlock image:transformedImage data:originalData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
}]; }];
} else { } else {