For FLAnimatedImageView, Use dispatch_group to maintain setImageBlock and completionBlock order. Ensure that completionBlock is called after that animatedImage created

This commit is contained in:
DreamPiggy 2017-11-17 15:58:43 +08:00
parent a9551b8591
commit 09750dcd2a
3 changed files with 30 additions and 12 deletions

View File

@ -47,6 +47,7 @@
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock {
__weak typeof(self)weakSelf = self;
dispatch_group_t group = dispatch_group_create();
[self sd_internalSetImageWithURL:url
placeholderImage:placeholder
options:options
@ -61,15 +62,18 @@
FLAnimatedImage *animatedImage = [FLAnimatedImage animatedImageWithGIFData:imageData];
dispatch_main_async_safe(^{
weakSelf.animatedImage = animatedImage;
dispatch_group_leave(group);
});
});
} else {
weakSelf.image = image;
weakSelf.animatedImage = nil;
dispatch_group_leave(group);
}
}
progress:progressBlock
completed:completedBlock];
completed:completedBlock
context:@{SDWebImageInternalSetImageGroupKey : group}];
}
@end

View File

@ -12,7 +12,10 @@
#import "SDWebImageManager.h"
FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageInternalSetImageInGlobalQueueKey;
/**
A Dispatch group to maintain setImageBlock and completionBlock. This key should only be used internal and may be changed in the future. (dispatch_group_t)
*/
FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageInternalSetImageGroupKey;
typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData);

View File

@ -13,7 +13,7 @@
#import "objc/runtime.h"
#import "UIView+WebCacheOperation.h"
NSString * const SDWebImageInternalSetImageInGlobalQueueKey = @"setImageInGlobalQueue";
NSString * const SDWebImageInternalSetImageGroupKey = @"setImageGroup";
static char imageURLKey;
@ -52,6 +52,10 @@ static char TAG_ACTIVITY_SHOW;
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (!(options & SDWebImageDelayPlaceholder)) {
if ([context valueForKey:SDWebImageInternalSetImageGroupKey]) {
dispatch_group_t group = [context valueForKey:SDWebImageInternalSetImageGroupKey];
dispatch_group_enter(group);
}
dispatch_main_async_safe(^{
[self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock];
});
@ -100,16 +104,23 @@ static char TAG_ACTIVITY_SHOW;
targetImage = placeholder;
targetData = nil;
}
BOOL shouldUseGlobalQueue = NO;
if (context && [context valueForKey:SDWebImageInternalSetImageInGlobalQueueKey]) {
shouldUseGlobalQueue = [[context valueForKey:SDWebImageInternalSetImageInGlobalQueueKey] boolValue];
}
dispatch_queue_t targetQueue = shouldUseGlobalQueue ? dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) : dispatch_get_main_queue();
dispatch_queue_async_safe(targetQueue, ^{
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
dispatch_main_async_safe(callCompletedBlockClojure);
});
if ([context valueForKey:SDWebImageInternalSetImageGroupKey]) {
dispatch_group_t group = [context valueForKey:SDWebImageInternalSetImageGroupKey];
dispatch_group_enter(group);
dispatch_main_async_safe(^{
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
dispatch_main_async_safe(callCompletedBlockClojure);
});
return;
} else {
dispatch_main_async_safe(^{
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
callCompletedBlockClojure();
});
}
}];
[self sd_setImageLoadOperation:operation forKey:validOperationKey];
} else {