Merge pull request #3429 from dreampiggy/perf/remove_conforms_to_protocol
Replace conformsToProtocol call with appropriate respondsToSelector check to improve performance
This commit is contained in:
commit
6ce59aa8c1
|
@ -471,7 +471,7 @@
|
||||||
{
|
{
|
||||||
if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)] && image.sd_isIncremental && [image respondsToSelector:@selector(animatedCoder)]) {
|
if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)] && image.sd_isIncremental && [image respondsToSelector:@selector(animatedCoder)]) {
|
||||||
id<SDAnimatedImageCoder> animatedCoder = [(id<SDAnimatedImage>)image animatedCoder];
|
id<SDAnimatedImageCoder> animatedCoder = [(id<SDAnimatedImage>)image animatedCoder];
|
||||||
if ([animatedCoder conformsToProtocol:@protocol(SDProgressiveImageCoder)]) {
|
if ([animatedCoder respondsToSelector:@selector(initIncrementalWithOptions:)]) {
|
||||||
return (id<SDAnimatedImageCoder, SDProgressiveImageCoder>)animatedCoder;
|
return (id<SDAnimatedImageCoder, SDProgressiveImageCoder>)animatedCoder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,7 +245,7 @@ static NSString * _defaultDiskCacheDirectory;
|
||||||
dispatch_async(self.ioQueue, ^{
|
dispatch_async(self.ioQueue, ^{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
NSData *data = imageData;
|
NSData *data = imageData;
|
||||||
if (!data && [image conformsToProtocol:@protocol(SDAnimatedImage)]) {
|
if (!data && [image respondsToSelector:@selector(animatedImageData)]) {
|
||||||
// If image is custom animated image class, prefer its original animated data
|
// If image is custom animated image class, prefer its original animated data
|
||||||
data = [((id<SDAnimatedImage>)image) animatedImageData];
|
data = [((id<SDAnimatedImage>)image) animatedImageData];
|
||||||
}
|
}
|
||||||
|
@ -440,8 +440,7 @@ static NSString * _defaultDiskCacheDirectory;
|
||||||
if (image) {
|
if (image) {
|
||||||
if (options & SDImageCacheDecodeFirstFrameOnly) {
|
if (options & SDImageCacheDecodeFirstFrameOnly) {
|
||||||
// Ensure static image
|
// Ensure static image
|
||||||
Class animatedImageClass = image.class;
|
if (image.sd_isAnimated) {
|
||||||
if (image.sd_isAnimated || ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)])) {
|
|
||||||
#if SD_MAC
|
#if SD_MAC
|
||||||
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
|
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
|
||||||
#else
|
#else
|
||||||
|
@ -574,8 +573,7 @@ static NSString * _defaultDiskCacheDirectory;
|
||||||
if (image) {
|
if (image) {
|
||||||
if (options & SDImageCacheDecodeFirstFrameOnly) {
|
if (options & SDImageCacheDecodeFirstFrameOnly) {
|
||||||
// Ensure static image
|
// Ensure static image
|
||||||
Class animatedImageClass = image.class;
|
if (image.sd_isAnimated) {
|
||||||
if (image.sd_isAnimated || ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)])) {
|
|
||||||
#if SD_MAC
|
#if SD_MAC
|
||||||
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
|
image = [[NSImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:kCGImagePropertyOrientationUp];
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -94,10 +94,8 @@ UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSS
|
||||||
CGFloat scale = [coderOptions[SDImageCoderDecodeScaleFactor] doubleValue];
|
CGFloat scale = [coderOptions[SDImageCoderDecodeScaleFactor] doubleValue];
|
||||||
|
|
||||||
// Grab the image coder
|
// Grab the image coder
|
||||||
id<SDImageCoder> imageCoder;
|
id<SDImageCoder> imageCoder = context[SDWebImageContextImageCoder];
|
||||||
if ([context[SDWebImageContextImageCoder] conformsToProtocol:@protocol(SDImageCoder)]) {
|
if (!imageCoder) {
|
||||||
imageCoder = context[SDWebImageContextImageCoder];
|
|
||||||
} else {
|
|
||||||
imageCoder = [SDImageCodersManager sharedManager];
|
imageCoder = [SDImageCodersManager sharedManager];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +126,6 @@ UIImage * _Nullable SDImageCacheDecodeImageData(NSData * _Nonnull imageData, NSS
|
||||||
if (lazyDecode) {
|
if (lazyDecode) {
|
||||||
// lazyDecode = NO means we should not forceDecode, highest priority
|
// lazyDecode = NO means we should not forceDecode, highest priority
|
||||||
shouldDecode = NO;
|
shouldDecode = NO;
|
||||||
} else if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {
|
|
||||||
// `SDAnimatedImage` do not decode
|
|
||||||
shouldDecode = NO;
|
|
||||||
} else if (image.sd_isAnimated) {
|
|
||||||
// animated image do not decode
|
|
||||||
shouldDecode = NO;
|
|
||||||
}
|
}
|
||||||
if (shouldDecode) {
|
if (shouldDecode) {
|
||||||
image = [SDImageCoderHelper decodedImageWithImage:image];
|
image = [SDImageCoderHelper decodedImageWithImage:image];
|
||||||
|
|
|
@ -23,8 +23,8 @@ static NSString * kSDCGImageSourceRasterizationDPI = @"kCGImageSourceRasterizati
|
||||||
// Specify File Size for lossy format encoding, like JPEG
|
// Specify File Size for lossy format encoding, like JPEG
|
||||||
static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize";
|
static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize";
|
||||||
|
|
||||||
// Only assert on Debug mode and Simulator
|
// Only assert on Debug mode
|
||||||
#define SD_CHECK_CGIMAGE_RETAIN_SOURCE DEBUG && TARGET_OS_SIMULATOR && \
|
#define SD_CHECK_CGIMAGE_RETAIN_SOURCE DEBUG && \
|
||||||
((__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0)) || \
|
((__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0)) || \
|
||||||
((__TV_OS_VERSION_MAX_ALLOWED >= __TVOS_15_0))
|
((__TV_OS_VERSION_MAX_ALLOWED >= __TVOS_15_0))
|
||||||
|
|
||||||
|
@ -300,10 +300,12 @@ static CGImageRef __nullable SDCGImageCreateCopy(CGImageRef cg_nullable image) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if SD_CHECK_CGIMAGE_RETAIN_SOURCE
|
#if SD_CHECK_CGIMAGE_RETAIN_SOURCE
|
||||||
// Assert here to check CGImageRef should not retain the CGImageSourceRef and has possible thread-safe issue (this is behavior on iOS 15+)
|
if (@available(iOS 15, tvOS 15, *)) {
|
||||||
// If assert hit, fire issue to https://github.com/SDWebImage/SDWebImage/issues and we update the condition for this behavior check
|
// Assert here to check CGImageRef should not retain the CGImageSourceRef and has possible thread-safe issue (this is behavior on iOS 15+)
|
||||||
extern CGImageSourceRef CGImageGetImageSource(CGImageRef);
|
// If assert hit, fire issue to https://github.com/SDWebImage/SDWebImage/issues and we update the condition for this behavior check
|
||||||
NSCAssert(!CGImageGetImageSource(imageRef), @"Animated Coder created CGImageRef should not retain CGImageSourceRef, which may cause thread-safe issue without lock");
|
extern CGImageSourceRef CGImageGetImageSource(CGImageRef);
|
||||||
|
NSCAssert(!CGImageGetImageSource(imageRef), @"Animated Coder created CGImageRef should not retain CGImageSourceRef, which may cause thread-safe issue without lock");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SD_UIKIT || SD_WATCH
|
#if SD_UIKIT || SD_WATCH
|
||||||
|
|
|
@ -47,10 +47,8 @@ UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NS
|
||||||
CGFloat scale = [coderOptions[SDImageCoderDecodeScaleFactor] doubleValue];
|
CGFloat scale = [coderOptions[SDImageCoderDecodeScaleFactor] doubleValue];
|
||||||
|
|
||||||
// Grab the image coder
|
// Grab the image coder
|
||||||
id<SDImageCoder> imageCoder;
|
id<SDImageCoder> imageCoder = context[SDWebImageContextImageCoder];
|
||||||
if ([context[SDWebImageContextImageCoder] conformsToProtocol:@protocol(SDImageCoder)]) {
|
if (!imageCoder) {
|
||||||
imageCoder = context[SDWebImageContextImageCoder];
|
|
||||||
} else {
|
|
||||||
imageCoder = [SDImageCodersManager sharedManager];
|
imageCoder = [SDImageCodersManager sharedManager];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +79,6 @@ UIImage * _Nullable SDImageLoaderDecodeImageData(NSData * _Nonnull imageData, NS
|
||||||
if (lazyDecode) {
|
if (lazyDecode) {
|
||||||
// lazyDecode = NO means we should not forceDecode, highest priority
|
// lazyDecode = NO means we should not forceDecode, highest priority
|
||||||
shouldDecode = NO;
|
shouldDecode = NO;
|
||||||
} else if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {
|
|
||||||
// `SDAnimatedImage` do not decode
|
|
||||||
shouldDecode = NO;
|
|
||||||
} else if (image.sd_isAnimated) {
|
|
||||||
// animated image do not decode
|
|
||||||
shouldDecode = NO;
|
|
||||||
}
|
}
|
||||||
if (shouldDecode) {
|
if (shouldDecode) {
|
||||||
image = [SDImageCoderHelper decodedImageWithImage:image];
|
image = [SDImageCoderHelper decodedImageWithImage:image];
|
||||||
|
@ -120,7 +112,7 @@ UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull im
|
||||||
if (!progressiveCoder) {
|
if (!progressiveCoder) {
|
||||||
id<SDProgressiveImageCoder> imageCoder = context[SDWebImageContextImageCoder];
|
id<SDProgressiveImageCoder> imageCoder = context[SDWebImageContextImageCoder];
|
||||||
// Check the progressive coder if provided
|
// Check the progressive coder if provided
|
||||||
if ([imageCoder conformsToProtocol:@protocol(SDProgressiveImageCoder)]) {
|
if ([imageCoder respondsToSelector:@selector(initIncrementalWithOptions:)]) {
|
||||||
progressiveCoder = [[[imageCoder class] alloc] initIncrementalWithOptions:coderOptions];
|
progressiveCoder = [[[imageCoder class] alloc] initIncrementalWithOptions:coderOptions];
|
||||||
} else {
|
} else {
|
||||||
// We need to create a new instance for progressive decoding to avoid conflicts
|
// We need to create a new instance for progressive decoding to avoid conflicts
|
||||||
|
@ -143,7 +135,7 @@ UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull im
|
||||||
if (!decodeFirstFrame) {
|
if (!decodeFirstFrame) {
|
||||||
// check whether we should use `SDAnimatedImage`
|
// check whether we should use `SDAnimatedImage`
|
||||||
Class animatedImageClass = context[SDWebImageContextAnimatedImageClass];
|
Class animatedImageClass = context[SDWebImageContextAnimatedImageClass];
|
||||||
if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)] && [progressiveCoder conformsToProtocol:@protocol(SDAnimatedImageCoder)]) {
|
if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)] && [progressiveCoder respondsToSelector:@selector(animatedImageFrameAtIndex:)]) {
|
||||||
image = [[animatedImageClass alloc] initWithAnimatedCoder:(id<SDAnimatedImageCoder>)progressiveCoder scale:scale];
|
image = [[animatedImageClass alloc] initWithAnimatedCoder:(id<SDAnimatedImageCoder>)progressiveCoder scale:scale];
|
||||||
if (image) {
|
if (image) {
|
||||||
// Progressive decoding does not preload frames
|
// Progressive decoding does not preload frames
|
||||||
|
@ -164,12 +156,6 @@ UIImage * _Nullable SDImageLoaderDecodeProgressiveImageData(NSData * _Nonnull im
|
||||||
if (lazyDecode) {
|
if (lazyDecode) {
|
||||||
// lazyDecode = NO means we should not forceDecode, highest priority
|
// lazyDecode = NO means we should not forceDecode, highest priority
|
||||||
shouldDecode = NO;
|
shouldDecode = NO;
|
||||||
} else if ([image.class conformsToProtocol:@protocol(SDAnimatedImage)]) {
|
|
||||||
// `SDAnimatedImage` do not decode
|
|
||||||
shouldDecode = NO;
|
|
||||||
} else if (image.sd_isAnimated) {
|
|
||||||
// animated image do not decode
|
|
||||||
shouldDecode = NO;
|
|
||||||
}
|
}
|
||||||
if (shouldDecode) {
|
if (shouldDecode) {
|
||||||
image = [SDImageCoderHelper decodedImageWithImage:image];
|
image = [SDImageCoderHelper decodedImageWithImage:image];
|
||||||
|
|
|
@ -353,9 +353,7 @@ static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
|
||||||
|
|
||||||
// Operation Class
|
// Operation Class
|
||||||
Class operationClass = self.config.operationClass;
|
Class operationClass = self.config.operationClass;
|
||||||
if (operationClass && [operationClass isSubclassOfClass:[NSOperation class]] && [operationClass conformsToProtocol:@protocol(SDWebImageDownloaderOperation)]) {
|
if (!operationClass) {
|
||||||
// Custom operation class
|
|
||||||
} else {
|
|
||||||
operationClass = [SDWebImageDownloaderOperation class];
|
operationClass = [SDWebImageDownloaderOperation class];
|
||||||
}
|
}
|
||||||
NSOperation<SDWebImageDownloaderOperation> *operation = [[operationClass alloc] initWithRequest:request inSession:self.session options:options context:context];
|
NSOperation<SDWebImageDownloaderOperation> *operation = [[operationClass alloc] initWithRequest:request inSession:self.session options:options context:context];
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "SDWebImageDownloaderConfig.h"
|
#import "SDWebImageDownloaderConfig.h"
|
||||||
|
#import "SDWebImageDownloaderOperation.h"
|
||||||
|
|
||||||
static SDWebImageDownloaderConfig * _defaultDownloaderConfig;
|
static SDWebImageDownloaderConfig * _defaultDownloaderConfig;
|
||||||
|
|
||||||
|
@ -48,5 +49,12 @@ static SDWebImageDownloaderConfig * _defaultDownloaderConfig;
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setOperationClass:(Class)operationClass {
|
||||||
|
if (operationClass) {
|
||||||
|
NSAssert([operationClass isSubclassOfClass:[NSOperation class]] && [operationClass conformsToProtocol:@protocol(SDWebImageDownloaderOperation)], @"Custom downloader operation class must subclass NSOperation and conform to `SDWebImageDownloaderOperation` protocol");
|
||||||
|
}
|
||||||
|
_operationClass = operationClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -170,7 +170,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
id<SDImageTransformer> transformer = self.transformer;
|
id<SDImageTransformer> transformer = self.transformer;
|
||||||
if (context[SDWebImageContextImageTransformer]) {
|
if (context[SDWebImageContextImageTransformer]) {
|
||||||
transformer = context[SDWebImageContextImageTransformer];
|
transformer = context[SDWebImageContextImageTransformer];
|
||||||
if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) {
|
if ([transformer isEqual:NSNull.null]) {
|
||||||
transformer = nil;
|
transformer = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,10 +286,8 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
progress:(nullable SDImageLoaderProgressBlock)progressBlock
|
progress:(nullable SDImageLoaderProgressBlock)progressBlock
|
||||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||||
// Grab the image cache to use
|
// Grab the image cache to use
|
||||||
id<SDImageCache> imageCache;
|
id<SDImageCache> imageCache = context[SDWebImageContextImageCache];
|
||||||
if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {
|
if (!imageCache) {
|
||||||
imageCache = context[SDWebImageContextImageCache];
|
|
||||||
} else {
|
|
||||||
imageCache = self.imageCache;
|
imageCache = self.imageCache;
|
||||||
}
|
}
|
||||||
// Get the query cache type
|
// Get the query cache type
|
||||||
|
@ -338,14 +336,11 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
progress:(nullable SDImageLoaderProgressBlock)progressBlock
|
progress:(nullable SDImageLoaderProgressBlock)progressBlock
|
||||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||||
// Grab the image cache to use, choose standalone original cache firstly
|
// Grab the image cache to use, choose standalone original cache firstly
|
||||||
id<SDImageCache> imageCache;
|
id<SDImageCache> imageCache = context[SDWebImageContextOriginalImageCache];
|
||||||
if ([context[SDWebImageContextOriginalImageCache] conformsToProtocol:@protocol(SDImageCache)]) {
|
if (!imageCache) {
|
||||||
imageCache = context[SDWebImageContextOriginalImageCache];
|
|
||||||
} else {
|
|
||||||
// if no standalone cache available, use default cache
|
// if no standalone cache available, use default cache
|
||||||
if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {
|
imageCache = context[SDWebImageContextImageCache];
|
||||||
imageCache = context[SDWebImageContextImageCache];
|
if (!imageCache) {
|
||||||
} else {
|
|
||||||
imageCache = self.imageCache;
|
imageCache = self.imageCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,10 +396,8 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the image loader to use
|
// Grab the image loader to use
|
||||||
id<SDImageLoader> imageLoader;
|
id<SDImageLoader> imageLoader = context[SDWebImageContextImageLoader];
|
||||||
if ([context[SDWebImageContextImageLoader] conformsToProtocol:@protocol(SDImageLoader)]) {
|
if (!imageLoader) {
|
||||||
imageLoader = context[SDWebImageContextImageLoader];
|
|
||||||
} else {
|
|
||||||
imageLoader = self.imageLoader;
|
imageLoader = self.imageLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +481,7 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
finished:(BOOL)finished
|
finished:(BOOL)finished
|
||||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||||
id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];
|
id<SDImageTransformer> transformer = context[SDWebImageContextImageTransformer];
|
||||||
if (![transformer conformsToProtocol:@protocol(SDImageTransformer)]) {
|
if ([transformer isEqual:NSNull.null]) {
|
||||||
transformer = nil;
|
transformer = nil;
|
||||||
}
|
}
|
||||||
// transformer check
|
// transformer check
|
||||||
|
@ -546,14 +539,11 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
finished:(BOOL)finished
|
finished:(BOOL)finished
|
||||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||||
// Grab the image cache to use, choose standalone original cache firstly
|
// Grab the image cache to use, choose standalone original cache firstly
|
||||||
id<SDImageCache> imageCache;
|
id<SDImageCache> imageCache = context[SDWebImageContextOriginalImageCache];
|
||||||
if ([context[SDWebImageContextOriginalImageCache] conformsToProtocol:@protocol(SDImageCache)]) {
|
if (!imageCache) {
|
||||||
imageCache = context[SDWebImageContextOriginalImageCache];
|
|
||||||
} else {
|
|
||||||
// if no standalone cache available, use default cache
|
// if no standalone cache available, use default cache
|
||||||
if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {
|
imageCache = context[SDWebImageContextImageCache];
|
||||||
imageCache = context[SDWebImageContextImageCache];
|
if (!imageCache) {
|
||||||
} else {
|
|
||||||
imageCache = self.imageCache;
|
imageCache = self.imageCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,10 +595,8 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
finished:(BOOL)finished
|
finished:(BOOL)finished
|
||||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||||
// Grab the image cache to use
|
// Grab the image cache to use
|
||||||
id<SDImageCache> imageCache;
|
id<SDImageCache> imageCache = context[SDWebImageContextImageCache];
|
||||||
if ([context[SDWebImageContextImageCache] conformsToProtocol:@protocol(SDImageCache)]) {
|
if (!imageCache) {
|
||||||
imageCache = context[SDWebImageContextImageCache];
|
|
||||||
} else {
|
|
||||||
imageCache = self.imageCache;
|
imageCache = self.imageCache;
|
||||||
}
|
}
|
||||||
BOOL waitStoreCache = SD_OPTIONS_CONTAINS(options, SDWebImageWaitStoreCache);
|
BOOL waitStoreCache = SD_OPTIONS_CONTAINS(options, SDWebImageWaitStoreCache);
|
||||||
|
@ -704,10 +692,8 @@ static id<SDImageLoader> _defaultImageLoader;
|
||||||
error:(nonnull NSError *)error
|
error:(nonnull NSError *)error
|
||||||
options:(SDWebImageOptions)options
|
options:(SDWebImageOptions)options
|
||||||
context:(nullable SDWebImageContext *)context {
|
context:(nullable SDWebImageContext *)context {
|
||||||
id<SDImageLoader> imageLoader;
|
id<SDImageLoader> imageLoader = context[SDWebImageContextImageLoader];
|
||||||
if ([context[SDWebImageContextImageLoader] conformsToProtocol:@protocol(SDImageLoader)]) {
|
if (!imageLoader) {
|
||||||
imageLoader = context[SDWebImageContextImageLoader];
|
|
||||||
} else {
|
|
||||||
imageLoader = self.imageLoader;
|
imageLoader = self.imageLoader;
|
||||||
}
|
}
|
||||||
// Check whether we should block failed url
|
// Check whether we should block failed url
|
||||||
|
|
|
@ -60,7 +60,7 @@ typedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;
|
||||||
operation = [operationDictionary objectForKey:key];
|
operation = [operationDictionary objectForKey:key];
|
||||||
}
|
}
|
||||||
if (operation) {
|
if (operation) {
|
||||||
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
|
if ([operation respondsToSelector:@selector(cancel)]) {
|
||||||
[operation cancel];
|
[operation cancel];
|
||||||
}
|
}
|
||||||
@synchronized (self) {
|
@synchronized (self) {
|
||||||
|
|
|
@ -84,7 +84,11 @@
|
||||||
NSURL *imageURL2 = [NSURL URLWithString:kTestPNGURL];
|
NSURL *imageURL2 = [NSURL URLWithString:kTestPNGURL];
|
||||||
NSURL *imageURL3 = [NSURL URLWithString:kTestGIFURL];
|
NSURL *imageURL3 = [NSURL URLWithString:kTestGIFURL];
|
||||||
// we try to set a usual NSOperation as operation class. Should not work
|
// we try to set a usual NSOperation as operation class. Should not work
|
||||||
downloader.config.operationClass = [NSOperation class];
|
@try {
|
||||||
|
downloader.config.operationClass = [NSOperation class];
|
||||||
|
} @catch (NSException *exception) {
|
||||||
|
expect(exception).notTo.beNil();
|
||||||
|
}
|
||||||
SDWebImageDownloadToken *token = [downloader downloadImageWithURL:imageURL1 options:0 progress:nil completed:nil];
|
SDWebImageDownloadToken *token = [downloader downloadImageWithURL:imageURL1 options:0 progress:nil completed:nil];
|
||||||
NSOperation<SDWebImageDownloaderOperation> *operation = token.downloadOperation;
|
NSOperation<SDWebImageDownloaderOperation> *operation = token.downloadOperation;
|
||||||
expect([operation class]).to.equal([SDWebImageDownloaderOperation class]);
|
expect([operation class]).to.equal([SDWebImageDownloaderOperation class]);
|
||||||
|
|
Loading…
Reference in New Issue