Update to <Fix multiple requests for same image and then canceling one> feature - exposed the SDWebImageDownloadToken class

This commit is contained in:
Bogdan Poplauschi 2016-05-23 07:38:48 +03:00
parent 13cfc5b89a
commit 8a78586d4e
2 changed files with 32 additions and 26 deletions

View File

@ -72,6 +72,17 @@ typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data,
typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers);
/**
* A token associated with each download. Can be used to cancel a download
*/
@interface SDWebImageDownloadToken : NSObject
@property (nonatomic, strong) NSURL *url;
@property (nonatomic, strong) id downloadOperationCancelToken;
@end
/**
* Asynchronous downloader dedicated and optimized for image loading.
*/
@ -176,19 +187,19 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
* before to be called a last time with the full image and finished argument
* set to YES. In case of error, the finished argument is always YES.
*
* @return A token that can be passed to -cancel: to cancel this operation
* @return A token (SDWebImageDownloadToken) that can be passed to -cancel: to cancel this operation
*/
- (id)downloadImageWithURL:(NSURL *)url
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock;
- (SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock;
/**
* Cancels a download that was previously queued using -downloadImageWithURL:options:progress:completed:
*
* @param token The token received from -downloadImageWithURL:options:progress:completed: that should be canceled.
*/
- (void)cancel:(id)token;
- (void)cancel:(SDWebImageDownloadToken *)token;
/**
* Sets the download queue suspension state

View File

@ -10,15 +10,9 @@
#import "SDWebImageDownloaderOperation.h"
#import <ImageIO/ImageIO.h>
@interface _SDWebImageDownloaderToken : NSObject
@property (nonatomic, strong) NSURL *url;
@property (nonatomic, strong) id downloadOperationCancelToken;
@implementation SDWebImageDownloadToken
@end
@implementation _SDWebImageDownloaderToken
@end
@interface SDWebImageDownloader ()
@ -119,7 +113,10 @@
_operationClass = operationClass ?: [SDWebImageDownloaderOperation class];
}
- (id)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock {
- (SDWebImageDownloadToken *)downloadImageWithURL:(NSURL *)url
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock {
__weak SDWebImageDownloader *wself = self;
return [self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^SDWebImageDownloaderOperation *{
@ -164,22 +161,20 @@
}];
}
- (void)cancel:(id)token {
if (![token isKindOfClass:[_SDWebImageDownloaderToken class]]) {
return;
}
- (void)cancel:(SDWebImageDownloadToken *)token {
dispatch_barrier_async(self.barrierQueue, ^{
_SDWebImageDownloaderToken *typedToken = (_SDWebImageDownloaderToken *)token;
SDWebImageDownloaderOperation *operation = self.URLOperations[typedToken.url];
BOOL canceled = [operation cancel:typedToken.downloadOperationCancelToken];
SDWebImageDownloaderOperation *operation = self.URLOperations[token.url];
BOOL canceled = [operation cancel:token.downloadOperationCancelToken];
if (canceled) {
[self.URLOperations removeObjectForKey:typedToken.url];
[self.URLOperations removeObjectForKey:token.url];
}
});
}
- (id)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL *)url createCallback:(SDWebImageDownloaderOperation *(^)())createCallback {
- (SDWebImageDownloadToken *)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock
completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock
forURL:(NSURL *)url
createCallback:(SDWebImageDownloaderOperation *(^)())createCallback {
// The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data.
if (url == nil) {
if (completedBlock != nil) {
@ -188,7 +183,7 @@
return nil;
}
__block _SDWebImageDownloaderToken *token = nil;
__block SDWebImageDownloadToken *token = nil;
dispatch_barrier_sync(self.barrierQueue, ^{
SDWebImageDownloaderOperation *operation = self.URLOperations[url];
@ -207,7 +202,7 @@
}
id downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock];
token = [_SDWebImageDownloaderToken new];
token = [SDWebImageDownloadToken new];
token.url = url;
token.downloadOperationCancelToken = downloadOperationCancelToken;
});