Merge pull request #2312 from dreampiggy/feature_cache_query_options

Add options to specify query cache sync/async behavior
This commit is contained in:
Bogdan Poplauschi 2018-05-09 12:41:57 +03:00 committed by GitHub
commit 02b0f8cb14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 28 deletions

View File

@ -14,36 +14,41 @@
typedef NS_OPTIONS(NSUInteger, SDImageCacheOptions) {
/**
* By default, we do not query disk data when the image is cached in memory. This mask can force to query disk data at the same time.
* By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDImageCacheQueryMemoryDataSync`
*/
SDImageCacheQueryDataWhenInMemory = 1 << 0,
SDImageCacheQueryMemoryData = 1 << 0,
/**
* By default, we query the memory cache synchronously, disk cache asynchronously. This mask can force to query disk cache synchronously.
* By default, when you only specify `SDImageCacheQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously.
*/
SDImageCacheQueryDiskSync = 1 << 1,
SDImageCacheQueryMemoryDataSync = 1 << 1,
/**
* By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously.
@note These 3 query options can be combined together. For the full list about these masks combination, see wiki page.
*/
SDImageCacheQueryDiskDataSync = 1 << 2,
/**
* By default, images are decoded respecting their original size. On iOS, this flag will scale down the
* images to a size compatible with the constrained memory of devices.
*/
SDImageCacheScaleDownLargeImages = 1 << 2,
SDImageCacheScaleDownLargeImages = 1 << 3,
/**
* We usually don't apply transform on animated images as most transformers could not manage animated images.
* Use this flag to transform them anyway.
*/
SDImageCacheTransformAnimatedImage = 1 << 3,
SDImageCacheTransformAnimatedImage = 1 << 4,
/**
* By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation.
* However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image.
*/
SDImageCacheAvoidDecodeImage = 1 << 4,
SDImageCacheAvoidDecodeImage = 1 << 5,
/**
* By default, we decode the animated image. This flag can force decode the first frame only and produece the static image.
*/
SDImageCacheDecodeFirstFrameOnly = 1 << 5,
SDImageCacheDecodeFirstFrameOnly = 1 << 6,
/**
* By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. This flag actually trigger `preloadAllAnimatedImageFrames = YES` after image load from disk cache
*/
SDImageCachePreloadAllFrames = 1 << 6
SDImageCachePreloadAllFrames = 1 << 7
};
/**

View File

@ -346,7 +346,7 @@
// First check the in-memory cache...
UIImage *image = [self imageFromMemoryCacheForKey:key];
BOOL shouldQueryMemoryOnly = (image && !(options & SDImageCacheQueryDataWhenInMemory));
BOOL shouldQueryMemoryOnly = (image && !(options & SDImageCacheQueryMemoryData));
if (shouldQueryMemoryOnly) {
if (doneBlock) {
doneBlock(image, nil, SDImageCacheTypeMemory);
@ -354,7 +354,13 @@
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
@ -366,7 +372,7 @@
UIImage *diskImage;
SDImageCacheType cacheType = SDImageCacheTypeDisk;
if (image) {
// the image is from in-memory cache
// the image is from in-memory cache, but need image data
diskImage = image;
cacheType = SDImageCacheTypeMemory;
} else if (diskData) {
@ -386,7 +392,7 @@
}
if (doneBlock) {
if (options & SDImageCacheQueryDiskSync) {
if (shouldQueryDiskSync) {
doneBlock(diskImage, diskData, cacheType);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
@ -397,8 +403,9 @@
}
};
if (options & SDImageCacheQueryDiskSync) {
queryDiskBlock();
// Query in ioQueue to keep IO-safe
if (shouldQueryDiskSync) {
dispatch_sync(self.ioQueue, queryDiskBlock);
} else {
dispatch_async(self.ioQueue, queryDiskBlock);
}
@ -578,8 +585,9 @@
- (id<SDWebImageOperation>)queryImageForKey:(NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context completion:(nullable SDImageCacheQueryCompletionBlock)completionBlock {
SDImageCacheOptions cacheOptions = 0;
if (options & SDWebImageQueryDataWhenInMemory) cacheOptions |= SDImageCacheQueryDataWhenInMemory;
if (options & SDWebImageQueryDiskSync) cacheOptions |= SDImageCacheQueryDiskSync;
if (options & SDWebImageQueryMemoryData) cacheOptions |= SDImageCacheQueryMemoryData;
if (options & SDWebImageQueryMemoryDataSync) cacheOptions |= SDImageCacheQueryMemoryDataSync;
if (options & SDWebImageQueryDiskDataSync) cacheOptions |= SDImageCacheQueryDiskDataSync;
if (options & SDWebImageTransformAnimatedImage) cacheOptions |= SDImageCacheTransformAnimatedImage;
if (options & SDWebImageDecodeFirstFrameOnly) cacheOptions |= SDImageCacheDecodeFirstFrameOnly;
if (options & SDWebImagePreloadAllFrames) cacheOptions |= SDImageCachePreloadAllFrames;

View File

@ -133,48 +133,54 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
SDWebImageScaleDownLargeImages = 1 << 12,
/**
* By default, we do not query disk data when the image is cached in memory. This mask can force to query disk data at the same time.
* This flag is recommend to be used with `SDWebImageQueryDiskSync` to ensure the image is loaded in the same runloop.
* By default, we do not query image data when the image is already cached in memory. This mask can force to query image data at the same time. However, this query is asynchronously unless you specify `SDWebImageQueryMemoryDataSync`
*/
SDWebImageQueryDataWhenInMemory = 1 << 13,
SDWebImageQueryMemoryData = 1 << 13,
/**
* By default, we query the memory cache synchronously, disk cache asynchronously. This mask can force to query disk cache synchronously to ensure that image is loaded in the same runloop.
* This flag can avoid flashing during cell reuse if you disable memory cache or in some other cases.
* By default, when you only specify `SDWebImageQueryMemoryData`, we query the memory image data asynchronously. Combined this mask as well to query the memory image data synchronously.
* @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing.
*/
SDWebImageQueryDiskSync = 1 << 14,
SDWebImageQueryMemoryDataSync = 1 << 14,
/**
* By default, when the memory cache miss, we query the disk cache asynchronously. This mask can force to query disk cache (when memory cache miss) synchronously.
* @note These 3 query options can be combined together. For the full list about these masks combination, see wiki page.
* @note Query data synchronously is not recommend, unless you want to ensure the image is loaded in the same runloop to avoid flashing during cell reusing.
*/
SDWebImageQueryDiskDataSync = 1 << 15,
/**
* By default, when the cache missed, the image is load from the loader. This flag can prevent this to load from cache only.
*/
SDWebImageFromCacheOnly = 1 << 15,
SDWebImageFromCacheOnly = 1 << 16,
/**
* By default, we query the cache before the image is load from the loader. This flag can prevent this to load from loader only.
*/
SDWebImageFromLoaderOnly = 1 << 16,
SDWebImageFromLoaderOnly = 1 << 17,
/**
* By default, when you use `SDWebImageTransition` to do some view transition after the image load finished, this transition is only applied for image download from the network. This mask can force to apply view transition for memory and disk cache as well.
*/
SDWebImageForceTransition = 1 << 17,
SDWebImageForceTransition = 1 << 18,
/**
* By default, we will decode the image in the background during cache query and download from the network. This can help to improve performance because when rendering image on the screen, it need to be firstly decoded. But this happen on the main queue by Core Animation.
* However, this process may increase the memory usage as well. If you are experiencing a issue due to excessive memory consumption, This flag can prevent decode the image.
*/
SDWebImageAvoidDecodeImage = 1 << 18,
SDWebImageAvoidDecodeImage = 1 << 19,
/**
* By default, we decode the animated image. This flag can force decode the first frame only and produece the static image.
*/
SDWebImageDecodeFirstFrameOnly = 1 << 19,
SDWebImageDecodeFirstFrameOnly = 1 << 20,
/**
* By default, for `SDAnimatedImage`, we decode the animated image frame during rendering to reduce memory usage. However, you can specify to preload all frames into memory to reduce CPU usage when the animated image is shared by lots of imageViews.
* This will actually trigger `preloadAllAnimatedImageFrames` in the background queue(Disk Cache & Download only).
*/
SDWebImagePreloadAllFrames = 1 << 20
SDWebImagePreloadAllFrames = 1 << 21
};