Attempting to fix rs/SDWebImage#84 by passing success/failure blocks in user info dictionary. This avoids holding success and failure block in manager object which is used as a singleton by the UIImageView and UIButton additions classes, thus repeatedly calling the same block multiple times when making multiple requests.

This commit is contained in:
andybee 2012-04-04 21:19:57 +02:00
parent 0cd7f6953b
commit ba818f0d65
1 changed files with 35 additions and 21 deletions

View File

@ -14,22 +14,12 @@
#if NS_BLOCKS_AVAILABLE
typedef void(^SuccessBlock)(UIImage *image);
typedef void(^FailureBlock)(NSError *error);
@interface SDWebImageManager ()
@property (nonatomic, copy) SuccessBlock successBlock;
@property (nonatomic, copy) FailureBlock failureBlock;
@end
#endif
static SDWebImageManager *instance;
@implementation SDWebImageManager
#if NS_BLOCKS_AVAILABLE
@synthesize successBlock;
@synthesize failureBlock;
#endif
- (id)init
{
if ((self = [super init]))
@ -122,9 +112,29 @@ static SDWebImageManager *instance;
#if NS_BLOCKS_AVAILABLE
- (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options success:(void (^)(UIImage *image))success failure:(void (^)(NSError *error))failure
{
self.successBlock = success;
self.failureBlock = failure;
[self downloadWithURL:url delegate:delegate options:options];
// repeated logic from above due to requirement for backwards compatability for iOS versions without blocks
// Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't
// throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString.
if ([url isKindOfClass:NSString.class])
{
url = [NSURL URLWithString:(NSString *)url];
}
if (!url || !delegate || (!(options & SDWebImageRetryFailed) && [failedURLs containsObject:url]))
{
return;
}
// Check the on-disk cache async so we don't block the main thread
[cacheDelegates addObject:delegate];
[cacheURLs addObject:url];
SuccessBlock successCopy = Block_copy(success);
FailureBlock failureCopy = Block_copy(failure);
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:delegate, @"delegate", url, @"url", [NSNumber numberWithInt:options], @"options", successCopy, @"success", failureCopy, @"failure", nil];
Block_release(successCopy);
Block_release(failureCopy);
[[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info];
}
#endif
@ -192,9 +202,10 @@ static SDWebImageManager *instance;
objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:), self, image, url);
}
#if NS_BLOCKS_AVAILABLE
if (self.successBlock)
if ([info objectForKey:@"success"])
{
self.successBlock(image);
SuccessBlock success = [info objectForKey:@"success"];
success(image);
}
#endif
@ -266,9 +277,10 @@ static SDWebImageManager *instance;
objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:), self, image, downloader.url);
}
#if NS_BLOCKS_AVAILABLE
if (self.successBlock)
if ([downloader.userInfo objectForKey:@"success"])
{
self.successBlock(image);
SuccessBlock success = [downloader.userInfo objectForKey:@"success"];
success(image);
}
#endif
}
@ -283,9 +295,10 @@ static SDWebImageManager *instance;
objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:), self, nil, downloader.url);
}
#if NS_BLOCKS_AVAILABLE
if (self.failureBlock)
if ([downloader.userInfo objectForKey:@"failure"])
{
self.failureBlock(nil);
FailureBlock failure = [downloader.userInfo objectForKey:@"failure"];
failure(nil);
}
#endif
}
@ -340,9 +353,10 @@ static SDWebImageManager *instance;
objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:), self, error, downloader.url);
}
#if NS_BLOCKS_AVAILABLE
if (self.failureBlock)
if ([downloader.userInfo objectForKey:@"failure"])
{
self.failureBlock(error);
FailureBlock failure = [downloader.userInfo objectForKey:@"failure"];
failure(error);
}
#endif