Fix the FLAnimatedImage compatible code issue by introduce a private API to check for the special cases

This commit is contained in:
DreamPiggy 2019-01-12 19:43:32 +08:00
parent 60f4365420
commit 605caa409d
3 changed files with 47 additions and 14 deletions

View File

@ -16,6 +16,19 @@
#import "UIImageView+WebCache.h" #import "UIImageView+WebCache.h"
#import "UIImage+MultiFormat.h" #import "UIImage+MultiFormat.h"
@interface UIView (PrivateWebCache)
- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
placeholderImage:(nullable UIImage *)placeholder
options:(SDWebImageOptions)options
operationKey:(nullable NSString *)operationKey
internalSetImageBlock:(nullable SDInternalSetImageBlock)setImageBlock
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock
context:(nullable NSDictionary<NSString *, id> *)context;
@end
static inline FLAnimatedImage * SDWebImageCreateFLAnimatedImage(FLAnimatedImageView *imageView, NSData *imageData) { static inline FLAnimatedImage * SDWebImageCreateFLAnimatedImage(FLAnimatedImageView *imageView, NSData *imageData) {
if ([NSData sd_imageFormatForImageData:imageData] != SDImageFormatGIF) { if ([NSData sd_imageFormatForImageData:imageData] != SDImageFormatGIF) {
return nil; return nil;
@ -119,7 +132,7 @@ static inline FLAnimatedImage * SDWebImageCreateFLAnimatedImage(FLAnimatedImageV
placeholderImage:placeholder placeholderImage:placeholder
options:options options:options
operationKey:nil operationKey:nil
setImageBlock:^(UIImage *image, NSData *imageData) { internalSetImageBlock:^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
__strong typeof(weakSelf)strongSelf = weakSelf; __strong typeof(weakSelf)strongSelf = weakSelf;
if (!strongSelf) { if (!strongSelf) {
dispatch_group_leave(group); dispatch_group_leave(group);
@ -138,7 +151,7 @@ static inline FLAnimatedImage * SDWebImageCreateFLAnimatedImage(FLAnimatedImageV
// Step 2. Check if original compressed image data is "GIF" // Step 2. Check if original compressed image data is "GIF"
BOOL isGIF = (image.sd_imageFormat == SDImageFormatGIF || [NSData sd_imageFormatForImageData:imageData] == SDImageFormatGIF); BOOL isGIF = (image.sd_imageFormat == SDImageFormatGIF || [NSData sd_imageFormatForImageData:imageData] == SDImageFormatGIF);
// Check if placeholder, which does not trigger a backup disk cache query // Check if placeholder, which does not trigger a backup disk cache query
BOOL isPlaceholder = (image == placeholder); BOOL isPlaceholder = !imageData && image && cacheType == SDImageCacheTypeNone;
if (!isGIF || isPlaceholder) { if (!isGIF || isPlaceholder) {
strongSelf.image = image; strongSelf.image = image;
strongSelf.animatedImage = nil; strongSelf.animatedImage = nil;

View File

@ -24,6 +24,7 @@ FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageExternalCustomManagerKey;
FOUNDATION_EXPORT const int64_t SDWebImageProgressUnitCountUnknown; /* 1LL */ FOUNDATION_EXPORT const int64_t SDWebImageProgressUnitCountUnknown; /* 1LL */
typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData); typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData);
typedef void(^SDInternalSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
@interface UIView (WebCache) @interface UIView (WebCache)

View File

@ -60,6 +60,25 @@ static char TAG_ACTIVITY_SHOW;
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock completed:(nullable SDExternalCompletionBlock)completedBlock
context:(nullable NSDictionary<NSString *, id> *)context { context:(nullable NSDictionary<NSString *, id> *)context {
SDInternalSetImageBlock internalSetImageBlock;
if (setImageBlock) {
internalSetImageBlock = ^(UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
if (setImageBlock) {
setImageBlock(image, imageData);
}
};
}
[self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options operationKey:operationKey internalSetImageBlock:internalSetImageBlock progress:progressBlock completed:completedBlock context:context];
}
- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
placeholderImage:(nullable UIImage *)placeholder
options:(SDWebImageOptions)options
operationKey:(nullable NSString *)operationKey
internalSetImageBlock:(nullable SDInternalSetImageBlock)setImageBlock
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock
context:(nullable NSDictionary<NSString *, id> *)context {
NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]); NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]);
[self sd_cancelImageLoadOperationWithKey:validOperationKey]; [self sd_cancelImageLoadOperationWithKey:validOperationKey];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
@ -70,7 +89,7 @@ static char TAG_ACTIVITY_SHOW;
dispatch_group_enter(group); dispatch_group_enter(group);
} }
dispatch_main_async_safe(^{ dispatch_main_async_safe(^{
[self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock]; [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock cacheType:SDImageCacheTypeNone imageURL:url];
}); });
} }
@ -157,7 +176,7 @@ static char TAG_ACTIVITY_SHOW;
#if SD_UIKIT || SD_MAC #if SD_UIKIT || SD_MAC
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL]; [sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
#else #else
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock]; [sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock cacheType:cacheType imageURL:imageURL];
#endif #endif
if (group) { if (group) {
// compatible code for FLAnimatedImage, because we assume completedBlock called after image was set. This will be removed in 5.x // compatible code for FLAnimatedImage, because we assume completedBlock called after image was set. This will be removed in 5.x
@ -190,13 +209,13 @@ static char TAG_ACTIVITY_SHOW;
[self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])]; [self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])];
} }
- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock { - (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDInternalSetImageBlock)setImageBlock cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL {
#if SD_UIKIT || SD_MAC #if SD_UIKIT || SD_MAC
[self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:0 imageURL:nil]; [self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:cacheType imageURL:imageURL];
#else #else
// watchOS does not support view transition. Simplify the logic // watchOS does not support view transition. Simplify the logic
if (setImageBlock) { if (setImageBlock) {
setImageBlock(image, imageData); setImageBlock(image, imageData, cacheType, imageURL);
} else if ([self isKindOfClass:[UIImageView class]]) { } else if ([self isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)self; UIImageView *imageView = (UIImageView *)self;
[imageView setImage:image]; [imageView setImage:image];
@ -205,21 +224,21 @@ static char TAG_ACTIVITY_SHOW;
} }
#if SD_UIKIT || SD_MAC #if SD_UIKIT || SD_MAC
- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock transition:(SDWebImageTransition *)transition cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL { - (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDInternalSetImageBlock)setImageBlock transition:(SDWebImageTransition *)transition cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL {
UIView *view = self; UIView *view = self;
SDSetImageBlock finalSetImageBlock; SDInternalSetImageBlock finalSetImageBlock;
if (setImageBlock) { if (setImageBlock) {
finalSetImageBlock = setImageBlock; finalSetImageBlock = setImageBlock;
} else if ([view isKindOfClass:[UIImageView class]]) { } else if ([view isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)view; UIImageView *imageView = (UIImageView *)view;
finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData) { finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) {
imageView.image = setImage; imageView.image = setImage;
}; };
} }
#if SD_UIKIT #if SD_UIKIT
else if ([view isKindOfClass:[UIButton class]]) { else if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view; UIButton *button = (UIButton *)view;
finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData){ finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData, SDImageCacheType setCacheType, NSURL *setImageURL) {
[button setImage:setImage forState:UIControlStateNormal]; [button setImage:setImage forState:UIControlStateNormal];
}; };
} }
@ -235,7 +254,7 @@ static char TAG_ACTIVITY_SHOW;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
[UIView transitionWithView:view duration:transition.duration options:transition.animationOptions animations:^{ [UIView transitionWithView:view duration:transition.duration options:transition.animationOptions animations:^{
if (finalSetImageBlock && !transition.avoidAutoSetImage) { if (finalSetImageBlock && !transition.avoidAutoSetImage) {
finalSetImageBlock(image, imageData); finalSetImageBlock(image, imageData, cacheType, imageURL);
} }
if (transition.animations) { if (transition.animations) {
transition.animations(view, image); transition.animations(view, image);
@ -255,7 +274,7 @@ static char TAG_ACTIVITY_SHOW;
context.timingFunction = transition.timingFunction; context.timingFunction = transition.timingFunction;
context.allowsImplicitAnimation = (transition.animationOptions & SDWebImageAnimationOptionAllowsImplicitAnimation); context.allowsImplicitAnimation = (transition.animationOptions & SDWebImageAnimationOptionAllowsImplicitAnimation);
if (finalSetImageBlock && !transition.avoidAutoSetImage) { if (finalSetImageBlock && !transition.avoidAutoSetImage) {
finalSetImageBlock(image, imageData); finalSetImageBlock(image, imageData, cacheType, imageURL);
} }
if (transition.animations) { if (transition.animations) {
transition.animations(view, image); transition.animations(view, image);
@ -269,7 +288,7 @@ static char TAG_ACTIVITY_SHOW;
#endif #endif
} else { } else {
if (finalSetImageBlock) { if (finalSetImageBlock) {
finalSetImageBlock(image, imageData); finalSetImageBlock(image, imageData, cacheType, imageURL);
} }
} }
} }