Merge pull request #2162 from dreampiggy/feature_query_cache_options
Feature query cache options
This commit is contained in:
commit
09e90b5215
|
@ -46,8 +46,10 @@
|
|||
options:(SDWebImageOptions)options
|
||||
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
__weak typeof(self)weakSelf = self;
|
||||
options |= SDWebImageQueryDiskDataWhenInMemory;
|
||||
options |= SDWebImageQueryDiskDataSync;
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
__weak typeof(self)weakSelf = self;
|
||||
[self sd_internalSetImageWithURL:url
|
||||
placeholderImage:placeholder
|
||||
options:options
|
||||
|
|
|
@ -25,6 +25,17 @@ typedef NS_ENUM(NSInteger, SDImageCacheType) {
|
|||
SDImageCacheTypeMemory
|
||||
};
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
|
||||
/**
|
||||
* By default, we do not query disk cache when the image is cached in memory. This mask can force query disk data at the same time.
|
||||
*/
|
||||
SDImageCacheQueryDiskDataWhenInMemory = 1 << 0,
|
||||
/**
|
||||
* By default, we query the memory cache synchonized, disk cache asynchronized. This mask can force to query disk cache synchonized.
|
||||
*/
|
||||
SDImageCacheQueryDiskDataSync = 1 << 1
|
||||
};
|
||||
|
||||
typedef void(^SDCacheQueryCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType);
|
||||
|
||||
typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
|
||||
|
@ -166,6 +177,17 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*/
|
||||
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock;
|
||||
|
||||
/**
|
||||
* Operation that queries the cache asynchronously and call the completion when done.
|
||||
*
|
||||
* @param key The unique key used to store the wanted image
|
||||
* @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
|
||||
*
|
||||
* @return a NSOperation instance containing the cache op
|
||||
*/
|
||||
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock;
|
||||
|
||||
/**
|
||||
* Query the memory cache synchronously.
|
||||
*
|
||||
|
|
|
@ -322,6 +322,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
- (nullable UIImage *)diskImageForKey:(nullable NSString *)key {
|
||||
NSData *data = [self diskImageDataBySearchingAllPathsForKey:key];
|
||||
return [self diskImageForKey:key data:data];
|
||||
}
|
||||
|
||||
- (nullable UIImage *)diskImageForKey:(nullable NSString *)key data:(nullable NSData *)data {
|
||||
if (data) {
|
||||
UIImage *image = [[SDWebImageCodersManager sharedInstance] decodedImageWithData:data];
|
||||
image = [self scaledImageForKey:key image:image];
|
||||
|
@ -338,50 +342,64 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
return SDScaledImageForKey(key, image);
|
||||
}
|
||||
|
||||
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock {
|
||||
- (NSOperation *)queryCacheOperationForKey:(NSString *)key done:(SDCacheQueryCompletedBlock)doneBlock {
|
||||
return [self queryCacheOperationForKey:key options:0 done:doneBlock];
|
||||
}
|
||||
|
||||
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(SDImageCacheOptions)options done:(nullable SDCacheQueryCompletedBlock)doneBlock {
|
||||
if (!key) {
|
||||
if (doneBlock) {
|
||||
doneBlock(nil, nil, SDImageCacheTypeNone);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
// First check the in-memory cache...
|
||||
UIImage *image = [self imageFromMemoryCacheForKey:key];
|
||||
if (image) {
|
||||
NSData *diskData = nil;
|
||||
if (image.images) {
|
||||
diskData = [self diskImageDataBySearchingAllPathsForKey:key];
|
||||
}
|
||||
if (image && !(options & SDImageCacheQueryDiskDataWhenInMemory)) {
|
||||
if (doneBlock) {
|
||||
doneBlock(image, diskData, SDImageCacheTypeMemory);
|
||||
doneBlock(image, nil, SDImageCacheTypeMemory);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
NSOperation *operation = [NSOperation new];
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
void(^queryDiskBlock)(void) = ^{
|
||||
if (operation.isCancelled) {
|
||||
// do not call the completion if cancelled
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@autoreleasepool {
|
||||
NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];
|
||||
UIImage *diskImage = [self diskImageForKey:key];
|
||||
if (diskImage && self.config.shouldCacheImagesInMemory) {
|
||||
NSUInteger cost = SDCacheCostForImage(diskImage);
|
||||
[self.memCache setObject:diskImage forKey:key cost:cost];
|
||||
UIImage *diskImage = image;
|
||||
if (!diskImage && diskData) {
|
||||
// decode image data only if in-memory cache missed
|
||||
diskImage = [self diskImageForKey:key data:diskData];
|
||||
if (diskImage && self.config.shouldCacheImagesInMemory) {
|
||||
NSUInteger cost = SDCacheCostForImage(diskImage);
|
||||
[self.memCache setObject:diskImage forKey:key cost:cost];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (doneBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (options & SDImageCacheQueryDiskDataSync) {
|
||||
doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
|
||||
});
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
if (options & SDImageCacheQueryDiskDataSync) {
|
||||
queryDiskBlock();
|
||||
} else {
|
||||
dispatch_async(self.ioQueue, queryDiskBlock);
|
||||
}
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,13 +105,6 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
return nil;
|
||||
}
|
||||
|
||||
SDImageFormat format = [NSData sd_imageFormatForImageData:data];
|
||||
if (format == SDImageFormatGIF) {
|
||||
// static single GIF need to be created animated for `FLAnimatedImage` logic
|
||||
// GIF does not support EXIF image orientation
|
||||
image = [UIImage animatedImageWithImages:@[image] duration:image.duration];
|
||||
return image;
|
||||
}
|
||||
UIImageOrientation orientation = [[self class] sd_imageOrientationFromImageData:data];
|
||||
if (orientation != UIImageOrientationUp) {
|
||||
image = [UIImage imageWithCGImage:image.CGImage
|
||||
|
|
|
@ -94,7 +94,19 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
|
|||
* images to a size compatible with the constrained memory of devices.
|
||||
* If `SDWebImageProgressiveDownload` flag is set the scale down is deactivated.
|
||||
*/
|
||||
SDWebImageScaleDownLargeImages = 1 << 12
|
||||
SDWebImageScaleDownLargeImages = 1 << 12,
|
||||
|
||||
/**
|
||||
* By default, we do not query disk cache when the image is cached in memory. This mask can force query disk data at the same time.
|
||||
* This options is recommend to be used with `SDWebImageQueryDiskDataSync` to ensure the image is loaded in the same runloop.
|
||||
*/
|
||||
SDWebImageQueryDiskDataWhenInMemory = 1 << 13,
|
||||
|
||||
/**
|
||||
* By default, we query the memory cache synchonized, disk cache asynchronized. This mask can force to query disk cache synchonized to ensure that image is loaded in the same runloop.
|
||||
* This can avoid flashing during cell reuse if you disable memory cache or in some other cases.
|
||||
*/
|
||||
SDWebImageQueryDiskDataSync = 1 << 14
|
||||
};
|
||||
|
||||
typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
|
||||
|
|
|
@ -143,8 +143,12 @@
|
|||
[self.runningOperations addObject:operation];
|
||||
}
|
||||
NSString *key = [self cacheKeyForURL:url];
|
||||
|
||||
SDImageCacheOptions cacheOptions = 0;
|
||||
if (options & SDWebImageQueryDiskDataWhenInMemory) cacheOptions |= SDImageCacheQueryDiskDataWhenInMemory;
|
||||
if (options & SDWebImageQueryDiskDataSync) cacheOptions |= SDImageCacheQueryDiskDataSync;
|
||||
|
||||
operation.cacheOperation = [self.imageCache queryCacheOperationForKey:key done:^(UIImage *cachedImage, NSData *cachedData, SDImageCacheType cacheType) {
|
||||
operation.cacheOperation = [self.imageCache queryCacheOperationForKey:key options:cacheOptions done:^(UIImage *cachedImage, NSData *cachedData, SDImageCacheType cacheType) {
|
||||
if (operation.isCancelled) {
|
||||
[self safelyRemoveOperationFromRunning:operation];
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue