diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index afe07f47..133af9dd 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -98,7 +98,7 @@ typedef enum SDImageCacheType SDImageCacheType; * * @param key The unique key used to store the wanted image */ -- (void)queryDiskCacheForKey:(NSString *)key done:(void (^)(UIImage *image, SDImageCacheType cacheType))doneBlock; +- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(void (^)(UIImage *image, SDImageCacheType cacheType))doneBlock; /** * Query the memory cache synchronously. diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index f2411a60..0b86507e 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -251,14 +251,16 @@ static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week return SDScaledImageForKey(key, image); } -- (void)queryDiskCacheForKey:(NSString *)key done:(void (^)(UIImage *image, SDImageCacheType cacheType))doneBlock +- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(void (^)(UIImage *image, SDImageCacheType cacheType))doneBlock { - if (!doneBlock) return; + NSOperation *operation = NSOperation.new; + + if (!doneBlock) return nil; if (!key) { doneBlock(nil, SDImageCacheTypeNone); - return; + return nil; } // First check the in-memory cache... @@ -266,11 +268,16 @@ static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week if (image) { doneBlock(image, SDImageCacheTypeMemory); - return; + return nil; } dispatch_async(self.ioQueue, ^ { + if (operation.isCancelled) + { + return; + } + @autoreleasepool { UIImage *diskImage = [self diskImageForKey:key]; @@ -286,6 +293,8 @@ static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week }); } }); + + return operation; } - (void)removeImageForKey:(NSString *)key diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 724c63d9..7e241377 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -14,6 +14,7 @@ @property (assign, nonatomic, getter = isCancelled) BOOL cancelled; @property (copy, nonatomic) void (^cancelBlock)(); +@property (strong, nonatomic) NSOperation *cacheOperation; @end @@ -108,9 +109,17 @@ } NSString *key = [self cacheKeyForURL:url]; - [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) + operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) { - if (operation.isCancelled) return; + if (operation.isCancelled) + { + @synchronized(self.runningOperations) + { + [self.runningOperations removeObject:operation]; + } + + return; + } if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { @@ -138,7 +147,7 @@ } id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { - if (weakOperation.cancelled) + if (weakOperation.isCancelled) { dispatch_main_sync_safe(^ { @@ -272,6 +281,11 @@ - (void)cancel { self.cancelled = YES; + if (self.cacheOperation) + { + [self.cacheOperation cancel]; + self.cacheOperation = nil; + } if (self.cancelBlock) { self.cancelBlock();