Use a weak pointerArray to store the operations for sd_setAnimationImagesWithURLs, avoid extra retain of operation instance
This commit is contained in:
parent
958a349c6c
commit
37f84ce6a6
|
@ -73,7 +73,7 @@
|
|||
[self sd_cancelCurrentAnimationImagesLoad];
|
||||
__weak __typeof(self)wself = self;
|
||||
|
||||
NSMutableArray<id<SDWebImageOperation>> *operationsArray = [[NSMutableArray alloc] init];
|
||||
NSPointerArray *operationsArray = [self sd_animationOperationArray];
|
||||
|
||||
[arrayOfURLs enumerateObjectsUsingBlock:^(NSURL *logoImageURL, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
id <SDWebImageOperation> operation = [[SDWebImageManager sharedManager] loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
|
||||
|
@ -103,14 +103,42 @@
|
|||
[sself startAnimating];
|
||||
});
|
||||
}];
|
||||
[operationsArray addObject:operation];
|
||||
@synchronized (self) {
|
||||
[operationsArray addPointer:(__bridge void *)(operation)];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
[self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];
|
||||
static char animationloadOperationKey;
|
||||
|
||||
// element is weak because operation instance is retained by SDWebImageManager's runningOperations property
|
||||
// we should use lock to keep thread-safe because these method may not be acessed from main queue
|
||||
- (NSPointerArray *)sd_animationOperationArray {
|
||||
@synchronized(self) {
|
||||
NSPointerArray *operationsArray = objc_getAssociatedObject(self, &animationloadOperationKey);
|
||||
if (operationsArray) {
|
||||
return operationsArray;
|
||||
}
|
||||
operationsArray = [NSPointerArray weakObjectsPointerArray];
|
||||
objc_setAssociatedObject(self, &animationloadOperationKey, operationsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
return operationsArray;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sd_cancelCurrentAnimationImagesLoad {
|
||||
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
|
||||
NSPointerArray *operationsArray = [self sd_animationOperationArray];
|
||||
if (operationsArray) {
|
||||
@synchronized (self) {
|
||||
for (id operation in operationsArray) {
|
||||
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < operationsArray.count; i++) {
|
||||
[operationsArray removePointerAtIndex:i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* @param operation the operation
|
||||
* @param key key for storing the operation
|
||||
*/
|
||||
- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key;
|
||||
- (void)sd_setImageLoadOperation:(nullable id<SDWebImageOperation>)operation forKey:(nullable NSString *)key;
|
||||
|
||||
/**
|
||||
* Cancel all operations for the current UIView and key
|
||||
|
|
|
@ -20,7 +20,7 @@ typedef NSMapTable<NSString *, id> SDOperationsDictionary;
|
|||
|
||||
@implementation UIView (WebCacheOperation)
|
||||
|
||||
- (SDOperationsDictionary *)operationDictionary {
|
||||
- (SDOperationsDictionary *)sd_operationDictionary {
|
||||
@synchronized(self) {
|
||||
SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
|
||||
if (operations) {
|
||||
|
@ -32,11 +32,11 @@ typedef NSMapTable<NSString *, id> SDOperationsDictionary;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)sd_setImageLoadOperation:(nullable id)operation forKey:(nullable NSString *)key {
|
||||
- (void)sd_setImageLoadOperation:(nullable id<SDWebImageOperation>)operation forKey:(nullable NSString *)key {
|
||||
if (key) {
|
||||
[self sd_cancelImageLoadOperationWithKey:key];
|
||||
if (operation) {
|
||||
SDOperationsDictionary *operationDictionary = [self operationDictionary];
|
||||
SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
|
||||
@synchronized (self) {
|
||||
[operationDictionary setObject:operation forKey:key];
|
||||
}
|
||||
|
@ -46,20 +46,14 @@ typedef NSMapTable<NSString *, id> SDOperationsDictionary;
|
|||
|
||||
- (void)sd_cancelImageLoadOperationWithKey:(nullable NSString *)key {
|
||||
// Cancel in progress downloader from queue
|
||||
SDOperationsDictionary *operationDictionary = [self operationDictionary];
|
||||
id operations;
|
||||
SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
|
||||
id operation;
|
||||
@synchronized (self) {
|
||||
operations = [operationDictionary objectForKey:key];
|
||||
operation = [operationDictionary objectForKey:key];
|
||||
}
|
||||
if (operations) {
|
||||
if ([operations isKindOfClass:[NSArray class]]) {
|
||||
for (id <SDWebImageOperation> operation in operations) {
|
||||
if (operation) {
|
||||
[operation cancel];
|
||||
}
|
||||
}
|
||||
} else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){
|
||||
[(id<SDWebImageOperation>) operations cancel];
|
||||
if (operation) {
|
||||
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]){
|
||||
[(id<SDWebImageOperation>) operation cancel];
|
||||
}
|
||||
@synchronized (self) {
|
||||
[operationDictionary removeObjectForKey:key];
|
||||
|
@ -69,7 +63,7 @@ typedef NSMapTable<NSString *, id> SDOperationsDictionary;
|
|||
|
||||
- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key {
|
||||
if (key) {
|
||||
SDOperationsDictionary *operationDictionary = [self operationDictionary];
|
||||
SDOperationsDictionary *operationDictionary = [self sd_operationDictionary];
|
||||
@synchronized (self) {
|
||||
[operationDictionary removeObjectForKey:key];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue