Skip to content

Commit b903c3b

Browse files
committed
Updated the logic for YYImageCache from 5.19.2
Fix the issue about thumbnail key mixing issue
1 parent cda7a45 commit b903c3b

File tree

4 files changed

+89
-30
lines changed

4 files changed

+89
-30
lines changed

SDWebImageYYPlugin/Classes/YYCache/YYCacheBridge/YYCache+SDAdditions.h

+3
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@
1212
/// YYCache category to support `SDImageCache` protocol. This allow user who prefer YYCache to be used as SDWebImage's custom image cache
1313
@interface YYCache (SDAdditions) <SDImageCache>
1414

15+
/// Cache Config object - storing all kind of settings.
16+
@property (nonatomic, strong, readonly, nonnull) SDImageCacheConfig *config;
17+
1518
@end

SDWebImageYYPlugin/Classes/YYCache/YYCacheBridge/YYCache+SDAdditions.m

+84-30
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,76 @@
99
#import "YYCache+SDAdditions.h"
1010
#import "YYMemoryCache+SDAdditions.h"
1111
#import "YYDiskCache+SDAdditions.h"
12+
#import "SDImageTransformer.h" // TODO, remove this
13+
#import <objc/runtime.h>
1214

13-
static void SDYYPluginUnarchiveObject(NSData *data, UIImage *image) {
14-
if (!data || !image) {
15+
// TODO, remove this
16+
static BOOL SDIsThumbnailKey(NSString *key) {
17+
if ([key rangeOfString:@"-Thumbnail("].location != NSNotFound) {
18+
return YES;
19+
}
20+
return NO;
21+
}
22+
23+
@implementation YYCache (SDAdditions)
24+
25+
- (SDImageCacheConfig *)config {
26+
// Provided the default one
27+
SDImageCacheConfig *config = objc_getAssociatedObject(self, @selector(config));
28+
if (!config) {
29+
config = SDImageCacheConfig.defaultCacheConfig;
30+
config.shouldDisableiCloud
31+
[self setConfig:config];
32+
}
33+
return config;
34+
}
35+
36+
- (void)setConfig:(SDImageCacheConfig *)config {
37+
objc_setAssociatedObject(self, @selector(config), config, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
38+
}
39+
40+
- (void)_syncDiskToMemoryWithImage:(UIImage *)diskImage forKey:(NSString *)key {
41+
// earily check
42+
if (!self.config.shouldCacheImagesInMemory) {
43+
return;
44+
}
45+
if (!diskImage) {
46+
return;
47+
}
48+
// The disk -> memory sync logic, which should only store thumbnail image with thumbnail key
49+
// However, caller (like SDWebImageManager) will query full key, with thumbnail size, and get thubmnail image
50+
// We should add a check here, currently it's a hack
51+
if (diskImage.sd_isThumbnail && !SDIsThumbnailKey(key)) {
52+
SDImageCoderOptions *options = diskImage.sd_decodeOptions;
53+
CGSize thumbnailSize = CGSizeZero;
54+
NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize];
55+
if (thumbnailSizeValue != nil) {
56+
#if SD_MAC
57+
thumbnailSize = thumbnailSizeValue.sizeValue;
58+
#else
59+
thumbnailSize = thumbnailSizeValue.CGSizeValue;
60+
#endif
61+
}
62+
BOOL preserveAspectRatio = YES;
63+
NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio];
64+
if (preserveAspectRatioValue != nil) {
65+
preserveAspectRatio = preserveAspectRatioValue.boolValue;
66+
}
67+
// Calculate the actual thumbnail key
68+
NSString *thumbnailKey = SDThumbnailedKeyForKey(key, thumbnailSize, preserveAspectRatio);
69+
// Override the sync key
70+
key = thumbnailKey;
71+
}
72+
NSUInteger cost = diskImage.sd_memoryCost;
73+
[self.memoryCache setObject:diskImage forKey:key cost:cost];
74+
}
75+
76+
- (void)_unarchiveObjectWithImage:(UIImage *)image forKey:(NSString *)key {
77+
if (!image || !key) {
1578
return;
1679
}
1780
// Check extended data
18-
NSData *extendedData = [YYDiskCache getExtendedDataFromObject:data];
81+
NSData *extendedData = [self.diskCache extendedDataForKey:key];
1982
if (!extendedData) {
2083
return;
2184
}
@@ -41,8 +104,8 @@ static void SDYYPluginUnarchiveObject(NSData *data, UIImage *image) {
41104
image.sd_extendedObject = extendedObject;
42105
}
43106

44-
static void SDYYPluginArchiveObject(NSData *data, UIImage *image) {
45-
if (!data || !image) {
107+
- (void)_archivedDataWithImage:(UIImage *)image forKey:(NSString *)key {
108+
if (!image || !key) {
46109
return;
47110
}
48111
// Check extended data
@@ -68,12 +131,10 @@ static void SDYYPluginArchiveObject(NSData *data, UIImage *image) {
68131
}
69132
}
70133
if (extendedData) {
71-
[YYDiskCache setExtendedData:extendedData toObject:data];
134+
[self.diskCache setExtendedData:extendedData forKey:key];
72135
}
73136
}
74137

75-
@implementation YYCache (SDAdditions)
76-
77138
- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(SDWebImageContext *)context completion:(SDImageCacheQueryCompletionBlock)doneBlock {
78139
return [self queryImageForKey:key options:options context:context cacheType:SDImageCacheTypeAll completion:doneBlock];
79140
}
@@ -102,7 +163,7 @@ @implementation YYCache (SDAdditions)
102163
if (image) {
103164
if (options & SDWebImageDecodeFirstFrameOnly) {
104165
// Ensure static image
105-
if (image.sd_isAnimated) {
166+
if (image.sd_imageFrameCount > 1) {
106167
#if SD_MAC
107168
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
108169
#else
@@ -156,30 +217,23 @@ @implementation YYCache (SDAdditions)
156217
// the image is from in-memory cache, but need image data
157218
diskImage = image;
158219
} else if (diskData) {
159-
BOOL shouldCacheToMomery = YES;
220+
BOOL shouldCacheToMemory = YES;
160221
if (context[SDWebImageContextStoreCacheType]) {
161222
SDImageCacheType cacheType = [context[SDWebImageContextStoreCacheType] integerValue];
162-
shouldCacheToMomery = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory);
223+
shouldCacheToMemory = (cacheType == SDImageCacheTypeAll || cacheType == SDImageCacheTypeMemory);
163224
}
164-
CGSize thumbnailSize = CGSizeZero;
165-
NSValue *thumbnailSizeValue = context[SDWebImageContextImageThumbnailPixelSize];
166-
if (thumbnailSizeValue != nil) {
167-
#if SD_MAC
168-
thumbnailSize = thumbnailSizeValue.sizeValue;
169-
#else
170-
thumbnailSize = thumbnailSizeValue.CGSizeValue;
171-
#endif
172-
}
173-
if (thumbnailSize.width > 0 && thumbnailSize.height > 0) {
174-
// Query full size cache key which generate a thumbnail, should not write back to full size memory cache
175-
shouldCacheToMomery = NO;
225+
// Special case: If user query image in list for the same URL, to avoid decode and write **same** image object into disk cache multiple times, we query and check memory cache here again.
226+
if (shouldCacheToMemory && self.config.shouldCacheImagesInMemory) {
227+
diskImage = [self.memoryCache objectForKey:key];
176228
}
177229
// decode image data only if in-memory cache missed
178-
diskImage = SDImageCacheDecodeImageData(diskData, key, options, context);
179-
SDYYPluginUnarchiveObject(diskData, diskImage);
180-
if (shouldCacheToMomery && diskImage) {
181-
NSUInteger cost = diskImage.sd_memoryCost;
182-
[self.memoryCache setObject:diskImage forKey:key cost:cost];
230+
if (!diskImage) {
231+
diskImage = SDImageCacheDecodeImageData(diskData, key, options, context);
232+
[self _unarchiveObjectWithImage:diskImage forKey:key];
233+
// check if we need sync logic
234+
if (shouldCacheToMemory) {
235+
[self _syncDiskToMemoryWithImage:diskImage forKey:key];
236+
}
183237
}
184238
}
185239
return diskImage;
@@ -264,8 +318,8 @@ - (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSStri
264318
}
265319
}
266320
NSData *data = [[SDImageCodersManager sharedManager] encodedDataWithImage:image format:format options:context[SDWebImageContextImageEncodeOptions]];
267-
SDYYPluginArchiveObject(data, image);
268321
[self.diskCache setObject:data forKey:key withBlock:^{
322+
[self _archivedDataWithImage:image forKey:key];
269323
if (completionBlock) {
270324
[(queue ?: SDCallbackQueue.mainQueue) async:^{
271325
completionBlock();
@@ -274,8 +328,8 @@ - (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(NSStri
274328
}];
275329
});
276330
} else {
277-
SDYYPluginArchiveObject(data, image);
278331
[self.diskCache setObject:data forKey:key withBlock:^{
332+
[self _archivedDataWithImage:image forKey:key];
279333
if (completionBlock) {
280334
[(queue ?: SDCallbackQueue.mainQueue) async:^{
281335
completionBlock();

SDWebImageYYPlugin/Classes/YYCache/YYCacheBridge/YYDiskCache+SDAdditions.h

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
/// YYDiskCache category to support `SDDiskCache` protocol. This allow user who prefer YYDiskCache to be used as SDWebImage's custom disk cache
1212
@interface YYDiskCache (SDAdditions) <SDDiskCache>
1313

14+
/// Cache Config object - storing all kind of settings.
1415
@property (nonatomic, strong, readonly, nullable) SDImageCacheConfig *config;
1516

1617
@end

SDWebImageYYPlugin/Classes/YYCache/YYCacheBridge/YYMemoryCache+SDAdditions.h

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
/// YYMemoryCache category to support `SDMemoryCache` protocol. This allow user who prefer YYMemoryCache to be used as SDWebImage's custom memory cache
1212
@interface YYMemoryCache (SDAdditions) <SDMemoryCache>
1313

14+
/// Cache Config object - storing all kind of settings.
1415
@property (nonatomic, strong, readonly, nullable) SDImageCacheConfig *config;
1516

1617
@end

0 commit comments

Comments
 (0)