Added context option `callbackQueue` for advanced user to control which queue to callback
This is used for user who call SDWebImage outside from main queue and need precise queue control, such as avoid chain queue blocking (like AVKit lazy load)
This commit is contained in:
parent
4178d12a44
commit
43ec4726e1
|
@ -25,6 +25,8 @@
|
|||
320CAE172086F50500CFFC80 /* SDWebImageError.h in Headers */ = {isa = PBXBuildFile; fileRef = 320CAE132086F50500CFFC80 /* SDWebImageError.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
320CAE1B2086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; };
|
||||
320CAE1D2086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; };
|
||||
321117A9296573680001FC2C /* SDCallbackQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 321117A7296573680001FC2C /* SDCallbackQueue.h */; };
|
||||
321117AA296573680001FC2C /* SDCallbackQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 321117A8296573680001FC2C /* SDCallbackQueue.m */; };
|
||||
321B37832083290E00C0EA77 /* SDImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
321B37872083290E00C0EA77 /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDImageLoader.m */; };
|
||||
321B37892083290E00C0EA77 /* SDImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDImageLoader.m */; };
|
||||
|
@ -387,6 +389,8 @@
|
|||
320224BA203979BA00E9F285 /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDAnimatedImageRep.m; path = Core/SDAnimatedImageRep.m; sourceTree = "<group>"; };
|
||||
320CAE132086F50500CFFC80 /* SDWebImageError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDWebImageError.h; path = Core/SDWebImageError.h; sourceTree = "<group>"; };
|
||||
320CAE142086F50500CFFC80 /* SDWebImageError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDWebImageError.m; path = Core/SDWebImageError.m; sourceTree = "<group>"; };
|
||||
321117A7296573680001FC2C /* SDCallbackQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDCallbackQueue.h; path = Core/SDCallbackQueue.h; sourceTree = "<group>"; };
|
||||
321117A8296573680001FC2C /* SDCallbackQueue.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDCallbackQueue.m; path = Core/SDCallbackQueue.m; sourceTree = "<group>"; };
|
||||
321B377D2083290D00C0EA77 /* SDImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDImageLoader.h; path = Core/SDImageLoader.h; sourceTree = "<group>"; };
|
||||
321B377E2083290D00C0EA77 /* SDImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDImageLoader.m; path = Core/SDImageLoader.m; sourceTree = "<group>"; };
|
||||
321B377F2083290E00C0EA77 /* SDImageLoadersManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDImageLoadersManager.h; path = Core/SDImageLoadersManager.h; sourceTree = "<group>"; };
|
||||
|
@ -872,6 +876,8 @@
|
|||
325312C7200F09910046BF1E /* SDWebImageTransition.m */,
|
||||
32C0FDDF2013426C001B8F2D /* SDWebImageIndicator.h */,
|
||||
32C0FDE02013426C001B8F2D /* SDWebImageIndicator.m */,
|
||||
321117A7296573680001FC2C /* SDCallbackQueue.h */,
|
||||
321117A8296573680001FC2C /* SDCallbackQueue.m */,
|
||||
);
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
|
@ -957,6 +963,7 @@
|
|||
3250C9EE2355D9DA0093A896 /* SDWebImageDownloaderDecryptor.h in Headers */,
|
||||
32F7C0862030719600873181 /* UIImage+Transform.h in Headers */,
|
||||
321E60C01F38E91700405457 /* UIImage+ForceDecode.h in Headers */,
|
||||
321117A9296573680001FC2C /* SDCallbackQueue.h in Headers */,
|
||||
329F1243223FAD3400B309FD /* SDInternalMacros.h in Headers */,
|
||||
80B6DF7F2142B43300BCB334 /* NSImage+Compatibility.h in Headers */,
|
||||
32C0FDE32013426C001B8F2D /* SDWebImageIndicator.h in Headers */,
|
||||
|
@ -1205,6 +1212,7 @@
|
|||
4A2CAE221AB4BB7000B6BC39 /* SDWebImageManager.m in Sources */,
|
||||
4A2CAE191AB4BB6400B6BC39 /* SDWebImageCompat.m in Sources */,
|
||||
325C460B22339426004CAE11 /* SDWeakProxy.m in Sources */,
|
||||
321117AA296573680001FC2C /* SDCallbackQueue.m in Sources */,
|
||||
321B37892083290E00C0EA77 /* SDImageLoader.m in Sources */,
|
||||
32484771201775F600AF9E5A /* SDAnimatedImage.m in Sources */,
|
||||
807A12301F89636300EC2A9B /* SDImageCodersManager.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
|
||||
#import "SDWebImageDefine.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SDCallbackQueue : NSObject
|
||||
|
||||
@property (nonnull, class, readonly) SDCallbackQueue *mainQueue;
|
||||
|
||||
@property (nonnull, class, readonly) SDCallbackQueue *callerQueue;
|
||||
|
||||
@property (nonnull, class, readonly) SDCallbackQueue *globalQueue;
|
||||
|
||||
+ (SDCallbackQueue *)dispatchQueue:(dispatch_queue_t)queue;
|
||||
|
||||
- (void)sync:(SDWebImageNoParamsBlock)block;
|
||||
|
||||
- (void)async:(SDWebImageNoParamsBlock)block;
|
||||
|
||||
- (void)asyncSafe:(SDWebImageNoParamsBlock)block;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
|
||||
#import "SDCallbackQueue.h"
|
||||
|
||||
@implementation SDCallbackQueue
|
||||
|
||||
- (void)sync:(dispatch_block_t)block {
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -14,6 +14,7 @@
|
|||
#import "UIImage+MemoryCacheCost.h"
|
||||
#import "UIImage+Metadata.h"
|
||||
#import "UIImage+ExtendedCacheData.h"
|
||||
#import "SDCallbackQueue.h"
|
||||
|
||||
@interface SDImageCacheToken ()
|
||||
|
||||
|
@ -63,6 +64,8 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
@property (nonatomic, copy, readwrite, nonnull) NSString *diskCachePath;
|
||||
@property (nonatomic, strong, nullable) dispatch_queue_t ioQueue;
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image imageData:(nullable NSData *)imageData forKey:(nullable NSString *)key options:(SDWebImageOptions)options context:(nullable SDWebImageContext *)context cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -197,20 +200,20 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:YES completion:completionBlock];
|
||||
[self storeImage:image imageData:nil forKey:key options:0 context:nil cacheType:SDImageCacheTypeAll completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock];
|
||||
[self storeImage:image imageData:nil forKey:key options:0 context:nil cacheType:(toDisk ? SDImageCacheTypeAll : SDImageCacheTypeMemory) completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
[self storeImage:nil imageData:imageData forKey:key toDisk:YES completion:completionBlock];
|
||||
[self storeImage:nil imageData:imageData forKey:key options:0 context:nil cacheType:SDImageCacheTypeAll completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
|
@ -218,14 +221,15 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
return [self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:toDisk completion:completionBlock];
|
||||
return [self storeImage:image imageData:imageData forKey:key options:0 context:nil cacheType:(toDisk ? SDImageCacheTypeDisk : SDImageCacheTypeMemory) completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toMemory:(BOOL)toMemory
|
||||
toDisk:(BOOL)toDisk
|
||||
options:(SDWebImageOptions)options
|
||||
context:(nullable SDWebImageContext *)context
|
||||
cacheType:(SDImageCacheType)cacheType
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
if ((!image && !imageData) || !key) {
|
||||
if (completionBlock) {
|
||||
|
@ -233,6 +237,8 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
}
|
||||
return;
|
||||
}
|
||||
BOOL toMemory = cacheType == SDImageCacheTypeMemory || cacheType == SDImageCacheTypeAll;
|
||||
BOOL toDisk = cacheType == SDImageCacheTypeDisk || cacheType == SDImageCacheTypeAll;
|
||||
// if memory cache is enabled
|
||||
if (image && toMemory && self.config.shouldCacheImagesInMemory) {
|
||||
NSUInteger cost = image.sd_memoryCost;
|
||||
|
@ -245,6 +251,7 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
}
|
||||
return;
|
||||
}
|
||||
SDCallbackQueue *queue = context[SDWebImageContextCallbackQueue];
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
@autoreleasepool {
|
||||
NSData *data = imageData;
|
||||
|
@ -271,9 +278,9 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
}
|
||||
|
||||
if (completionBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[(queue ?: SDCallbackQueue.mainQueue) async:^{
|
||||
completionBlock();
|
||||
});
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -609,6 +616,7 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
// 2. in-memory cache miss & diskDataSync
|
||||
BOOL shouldQueryDiskSync = ((image && options & SDImageCacheQueryMemoryDataSync) ||
|
||||
(!image && options & SDImageCacheQueryDiskDataSync));
|
||||
SDCallbackQueue *queue = context[SDWebImageContextCallbackQueue];
|
||||
NSData* (^queryDiskDataBlock)(void) = ^NSData* {
|
||||
@synchronized (operation) {
|
||||
if (operation.isCancelled) {
|
||||
|
@ -680,7 +688,7 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
}
|
||||
}
|
||||
if (doneBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[(queue ?: SDCallbackQueue.mainQueue) async:^{
|
||||
// Dispatch from IO queue to main queue need time, user may call cancel during the dispatch timing
|
||||
// This check is here to avoid double callback (one is from `SDImageCacheToken` in sync)
|
||||
@synchronized (operation) {
|
||||
|
@ -689,7 +697,7 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
}
|
||||
}
|
||||
doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
|
||||
});
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -894,30 +902,7 @@ static NSString * _defaultDiskCacheDirectory;
|
|||
}
|
||||
|
||||
- (void)storeImage:(UIImage *)image imageData:(NSData *)imageData forKey:(nullable NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
switch (cacheType) {
|
||||
case SDImageCacheTypeNone: {
|
||||
[self storeImage:image imageData:imageData forKey:key toMemory:NO toDisk:NO completion:completionBlock];
|
||||
}
|
||||
break;
|
||||
case SDImageCacheTypeMemory: {
|
||||
[self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:NO completion:completionBlock];
|
||||
}
|
||||
break;
|
||||
case SDImageCacheTypeDisk: {
|
||||
[self storeImage:image imageData:imageData forKey:key toMemory:NO toDisk:YES completion:completionBlock];
|
||||
}
|
||||
break;
|
||||
case SDImageCacheTypeAll: {
|
||||
[self storeImage:image imageData:imageData forKey:key toMemory:YES toDisk:YES completion:completionBlock];
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
if (completionBlock) {
|
||||
completionBlock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
[self storeImage:image imageData:imageData forKey:key options:0 context:nil cacheType:cacheType completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)removeImageForKey:(NSString *)key cacheType:(SDImageCacheType)cacheType completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
|
|
|
@ -122,6 +122,25 @@ FOUNDATION_EXPORT void SDSetDecodeOptionsToContext(SDWebImageMutableContext * _N
|
|||
cacheType:(SDImageCacheType)cacheType
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
Store the image into image cache for the given key. If cache type is memory only, completion is called synchronously, else asynchronously.
|
||||
|
||||
@param image The image to store
|
||||
@param imageData The image data to be used for disk storage
|
||||
@param key The image cache key
|
||||
@param options A mask to specify options to use for this store
|
||||
@param context The context options to use. Pass `.storeCacheType` to control cache type, pass `.callbackQueue` to control callback queue
|
||||
@param cacheType The image store op cache type
|
||||
@param completionBlock A block executed after the operation is finished
|
||||
*/
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
options:(SDWebImageOptions)options
|
||||
context:(nullable SDWebImageContext *)context
|
||||
cacheType:(SDImageCacheType)cacheType
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
Remove the image from image cache for the given key. If cache type is memory only, completion is called synchronously, else asynchronously.
|
||||
|
||||
|
|
|
@ -221,6 +221,11 @@ FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextSetIma
|
|||
*/
|
||||
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCustomManager API_DEPRECATED("Use individual context option like .imageCache, .imageLoader and .imageTransformer instead", 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));
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextCallbackQueue;
|
||||
|
||||
/**
|
||||
A id<SDImageCache> instance which conforms to `SDImageCache` protocol. It's used to override the image manager's cache during the image loading pipeline.
|
||||
In other word, if you just want to specify a custom cache during image loading, you don't need to re-create a dummy SDWebImageManager instance with the cache. If not provided, use the image manager's cache (id<SDImageCache>)
|
||||
|
|
|
@ -127,6 +127,7 @@ inline UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage *
|
|||
|
||||
SDWebImageContextOption const SDWebImageContextSetImageOperationKey = @"setImageOperationKey";
|
||||
SDWebImageContextOption const SDWebImageContextCustomManager = @"customManager";
|
||||
SDWebImageContextOption const SDWebImageContextCallbackQueue = @"callbackQueue";
|
||||
SDWebImageContextOption const SDWebImageContextImageCache = @"imageCache";
|
||||
SDWebImageContextOption const SDWebImageContextImageLoader = @"imageLoader";
|
||||
SDWebImageContextOption const SDWebImageContextImageCoder = @"imageCoder";
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#import "SDWebImageDownloaderResponseModifier.h"
|
||||
#import "SDWebImageDownloaderDecryptor.h"
|
||||
#import "SDImageCacheDefine.h"
|
||||
#import "SDCallbackQueue.h"
|
||||
|
||||
// A handler to represent individual request
|
||||
@interface SDWebImageDownloaderOperationToken : NSObject
|
||||
|
@ -689,9 +690,9 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
}
|
||||
|
||||
- (void)callCompletionBlocksWithImage:(nullable UIImage *)image
|
||||
imageData:(nullable NSData *)imageData
|
||||
error:(nullable NSError *)error
|
||||
finished:(BOOL)finished {
|
||||
imageData:(nullable NSData *)imageData
|
||||
error:(nullable NSError *)error
|
||||
finished:(BOOL)finished {
|
||||
NSArray<SDWebImageDownloaderOperationToken *> *tokens;
|
||||
@synchronized (self) {
|
||||
tokens = [self.callbackTokens copy];
|
||||
|
@ -699,9 +700,10 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
for (SDWebImageDownloaderOperationToken *token in tokens) {
|
||||
SDWebImageDownloaderCompletedBlock completedBlock = token.completedBlock;
|
||||
if (completedBlock) {
|
||||
dispatch_main_async_safe(^{
|
||||
SDCallbackQueue *queue = self.context[SDWebImageContextCallbackQueue];
|
||||
[(queue ?: SDCallbackQueue.mainQueue) asyncSafe:^{
|
||||
completedBlock(image, imageData, error, finished);
|
||||
});
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -713,9 +715,10 @@ didReceiveResponse:(NSURLResponse *)response
|
|||
finished:(BOOL)finished {
|
||||
SDWebImageDownloaderCompletedBlock completedBlock = token.completedBlock;
|
||||
if (completedBlock) {
|
||||
dispatch_main_async_safe(^{
|
||||
SDCallbackQueue *queue = self.context[SDWebImageContextCallbackQueue];
|
||||
[(queue ?: SDCallbackQueue.mainQueue) asyncSafe:^{
|
||||
completedBlock(image, imageData, error, finished);
|
||||
});
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#import "SDAssociatedObject.h"
|
||||
#import "SDWebImageError.h"
|
||||
#import "SDInternalMacros.h"
|
||||
#import "SDCallbackQueue.h"
|
||||
|
||||
static id<SDImageCache> _defaultImageCache;
|
||||
static id<SDImageLoader> _defaultImageLoader;
|
||||
|
@ -213,11 +214,14 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
isFailedUrl = [self.failedURLs containsObject:url];
|
||||
SD_UNLOCK(_failedURLsLock);
|
||||
}
|
||||
|
||||
// Preprocess the options and context arg to decide the final the result for manager
|
||||
SDWebImageOptionsResult *result = [self processedResultForURL:url options:options context:context];
|
||||
|
||||
if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
|
||||
NSString *description = isFailedUrl ? @"Image url is blacklisted" : @"Image url is nil";
|
||||
NSInteger code = isFailedUrl ? SDWebImageErrorBlackListed : SDWebImageErrorInvalidURL;
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : description}] url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : description}] queue:result.context[SDWebImageContextCallbackQueue] url:url];
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
@ -225,9 +229,6 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
[self.runningOperations addObject:operation];
|
||||
SD_UNLOCK(_runningOperationsLock);
|
||||
|
||||
// Preprocess the options and context arg to decide the final the result for manager
|
||||
SDWebImageOptionsResult *result = [self processedResultForURL:url options:options context:context];
|
||||
|
||||
// Start the entry to load image from cache, the longest steps are below
|
||||
// Steps without transformer:
|
||||
// 1. query image from cache, miss
|
||||
|
@ -306,7 +307,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
@strongify(operation);
|
||||
if (!operation || operation.isCancelled) {
|
||||
// Image combined operation cancelled by user
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during querying the cache"}] url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during querying the cache"}] queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
[self safelyRemoveOperationFromRunning:operation];
|
||||
return;
|
||||
} else if (!cachedImage) {
|
||||
|
@ -360,7 +361,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
@strongify(operation);
|
||||
if (!operation || operation.isCancelled) {
|
||||
// Image combined operation cancelled by user
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during querying the cache"}] url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during querying the cache"}] queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
[self safelyRemoveOperationFromRunning:operation];
|
||||
return;
|
||||
} else if (!cachedImage) {
|
||||
|
@ -414,7 +415,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
if (cachedImage && options & SDWebImageRefreshCached) {
|
||||
// If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image
|
||||
// AND try to re-download it in order to let a chance to NSURLCache to refresh it from server.
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
// Pass the cached image to the image loader. The image loader should check whether the remote image is equal to the cached image.
|
||||
SDWebImageMutableContext *mutableContext;
|
||||
if (context) {
|
||||
|
@ -431,14 +432,14 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
@strongify(operation);
|
||||
if (!operation || operation.isCancelled) {
|
||||
// Image combined operation cancelled by user
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}] url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:[NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}] queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
} else if (cachedImage && options & SDWebImageRefreshCached && [error.domain isEqualToString:SDWebImageErrorDomain] && error.code == SDWebImageErrorCacheNotModified) {
|
||||
// Image refresh hit the NSURLCache cache, do not call the completion block
|
||||
} else if ([error.domain isEqualToString:SDWebImageErrorDomain] && error.code == SDWebImageErrorCancelled) {
|
||||
// Download operation cancelled by user before sending the request, don't block failed URL
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:error url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:error queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
} else if (error) {
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:error url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock error:error queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
BOOL shouldBlockFailedURL = [self shouldBlockFailedURLWithURL:url error:error options:options context:context];
|
||||
|
||||
if (shouldBlockFailedURL) {
|
||||
|
@ -461,11 +462,11 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
}
|
||||
}];
|
||||
} else if (cachedImage) {
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
[self safelyRemoveOperationFromRunning:operation];
|
||||
} else {
|
||||
// Image not in cache and download disallowed by delegate
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:nil data:nil error:nil cacheType:SDImageCacheTypeNone finished:YES url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:nil data:nil error:nil cacheType:SDImageCacheTypeNone finished:YES queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
[self safelyRemoveOperationFromRunning:operation];
|
||||
}
|
||||
}
|
||||
|
@ -605,13 +606,13 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
NSData *newData = [cacheSerializer cacheDataWithImage:image originalData:data imageURL:url];
|
||||
// Store image and data
|
||||
[self storeImage:image imageData:newData forKey:key imageCache:imageCache cacheType:storeCacheType finished:finished waitStoreCache:waitStoreCache completion:^{
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:image data:data error:nil cacheType:cacheType finished:finished url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:image data:data error:nil cacheType:cacheType finished:finished queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
}];
|
||||
});
|
||||
} else {
|
||||
// Store image and data
|
||||
[self storeImage:image imageData:data forKey:key imageCache:imageCache cacheType:storeCacheType finished:finished waitStoreCache:waitStoreCache completion:^{
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:image data:data error:nil cacheType:cacheType finished:finished url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completedBlock image:image data:data error:nil cacheType:cacheType finished:finished queue:context[SDWebImageContextCallbackQueue] url:url];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
@ -660,8 +661,9 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation
|
||||
completion:(nullable SDInternalCompletionBlock)completionBlock
|
||||
error:(nullable NSError *)error
|
||||
queue:(nullable SDCallbackQueue *)queue
|
||||
url:(nullable NSURL *)url {
|
||||
[self callCompletionBlockForOperation:operation completion:completionBlock image:nil data:nil error:error cacheType:SDImageCacheTypeNone finished:YES url:url];
|
||||
[self callCompletionBlockForOperation:operation completion:completionBlock image:nil data:nil error:error cacheType:SDImageCacheTypeNone finished:YES queue:queue url:url];
|
||||
}
|
||||
|
||||
- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation
|
||||
|
@ -671,11 +673,12 @@ static id<SDImageLoader> _defaultImageLoader;
|
|||
error:(nullable NSError *)error
|
||||
cacheType:(SDImageCacheType)cacheType
|
||||
finished:(BOOL)finished
|
||||
queue:(nullable SDCallbackQueue *)queue
|
||||
url:(nullable NSURL *)url {
|
||||
if (completionBlock) {
|
||||
dispatch_main_async_safe(^{
|
||||
[(queue ?: SDCallbackQueue.mainQueue) asyncSafe:^{
|
||||
completionBlock(image, data, error, cacheType, finished, url);
|
||||
});
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue