From bd6fc88c014f0b8149a45a5340f11c4d0e1c27c7 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 12 Sep 2011 17:19:57 +0200 Subject: [PATCH 1/4] allow imageRequestOperation to be cancelled --- AFNetworking/UIImageView+AFNetworking.m | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index d1f5070..425f8e3 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -87,6 +87,9 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"imageRequestOperat block:(void (^)(UIImage *image))block { if (!url) { + // stop loading image + [self.imageRequestOperation cancel]; + self.imageRequestOperation = nil; return; } @@ -105,14 +108,16 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"imageRequestOperat self.image = placeholderImage; self.imageRequestOperation = [AFImageRequestOperation operationWithRequest:request imageSize:imageSize options:options success:^(UIImage *image) { - if ([[request URL] isEqual:[[self.imageRequestOperation request] URL]]) { - self.image = image; - } else { - self.image = placeholderImage; - } - - if (block) { - block(image); + if (self.imageRequestOperation && ![self.imageRequestOperation isCancelled]) { + if ([[request URL] isEqual:[[self.imageRequestOperation request] URL]]) { + self.image = image; + } else { + self.image = placeholderImage; + } + + if (block) { + block(image); + } } }]; From 908d77aaafca000f7914ec0b0aba8f88f6e7b8ac Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 12 Sep 2011 17:20:50 +0200 Subject: [PATCH 2/4] execute custom block _before_ setting image This is particularly useful if you want to animate the image change, e.g. with a core animation block - that's not possible after image is changed. --- AFNetworking/UIImageView+AFNetworking.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index 425f8e3..2fa7b96 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -109,15 +109,15 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"imageRequestOperat self.imageRequestOperation = [AFImageRequestOperation operationWithRequest:request imageSize:imageSize options:options success:^(UIImage *image) { if (self.imageRequestOperation && ![self.imageRequestOperation isCancelled]) { + if (block) { + block(image); + } + if ([[request URL] isEqual:[[self.imageRequestOperation request] URL]]) { self.image = image; } else { self.image = placeholderImage; - } - - if (block) { - block(image); - } + } } }]; From 2fbc30d137e89addf606c303a2ec6551b533e33a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 12 Sep 2011 17:35:45 +0200 Subject: [PATCH 3/4] fix selector warnings, fix warning "ignore declaration shadows a local variable" with using MIN inside of MAX --- AFNetworking/AFHTTPRequestOperation.m | 43 +++++++++++++++------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 23695cb..0247377 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -23,6 +23,8 @@ #import "AFHTTPRequestOperation.h" #import "AFNetworkActivityIndicatorManager.h" +#define AFHTTPMinContentLength 1024 * 1024 * 8 + typedef enum { AFHTTPOperationReadyState = 1, AFHTTPOperationExecutingState = 2, @@ -107,6 +109,14 @@ static inline BOOL AFHTTPOperationStateTransitionIsValid(AFHTTPOperationState fr static NSThread *_networkRequestThread = nil; ++ (void)networkRequestThreadEntryPoint:(id)object { + do { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [[NSRunLoop currentRunLoop] run]; + [pool drain]; + } while (YES); +} + + (NSThread *)networkRequestThread { static dispatch_once_t oncePredicate; @@ -118,14 +128,6 @@ static NSThread *_networkRequestThread = nil; return _networkRequestThread; } -+ (void)networkRequestThreadEntryPoint:(id)object { - do { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [[NSRunLoop currentRunLoop] run]; - [pool drain]; - } while (YES); -} - + (id)operationWithRequest:(NSURLRequest *)urlRequest completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error))completion { @@ -246,16 +248,6 @@ static NSThread *_networkRequestThread = nil; return YES; } -- (void)start { - if (self.isFinished) { - return; - } - - self.state = AFHTTPOperationExecutingState; - - [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:YES modes:[self.runLoopModes allObjects]]; -} - - (void)operationDidStart { self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease]; @@ -269,6 +261,16 @@ static NSThread *_networkRequestThread = nil; } +- (void)start { + if (self.isFinished) { + return; + } + + self.state = AFHTTPOperationExecutingState; + + [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:YES modes:[self.runLoopModes allObjects]]; +} + - (void)cancel { self.isCancelled = YES; @@ -297,7 +299,10 @@ didReceiveResponse:(NSURLResponse *)response if (self.outputStream) { [self.outputStream open]; } else { - NSUInteger contentLength = MIN(MAX(abs(response.expectedContentLength), 1024), 1024 * 1024 * 8); + NSUInteger contentLength = MAX(abs(response.expectedContentLength), 1024); + if (contentLength < AFHTTPMinContentLength) { + contentLength = AFHTTPMinContentLength; + } self.dataAccumulator = [NSMutableData dataWithCapacity:contentLength]; } } From 1ec54e259578658be1308f22ae60ce6d270b735c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 12 Sep 2011 17:36:20 +0200 Subject: [PATCH 4/4] add BOOL if cache was used to load image This is useful for animation - if function directly returns, there's no need to animate the new image --- AFNetworking/UIImageView+AFNetworking.h | 2 +- AFNetworking/UIImageView+AFNetworking.m | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AFNetworking/UIImageView+AFNetworking.h b/AFNetworking/UIImageView+AFNetworking.h index 0b79875..72a19ec 100644 --- a/AFNetworking/UIImageView+AFNetworking.h +++ b/AFNetworking/UIImageView+AFNetworking.h @@ -39,6 +39,6 @@ placeholderImage:(UIImage *)placeholderImage imageSize:(CGSize)imageSize options:(AFImageRequestOptions)options - block:(void (^)(UIImage *image))block; + block:(void (^)(UIImage *image, BOOL cacheUsed))block; @end diff --git a/AFNetworking/UIImageView+AFNetworking.m b/AFNetworking/UIImageView+AFNetworking.m index 2fa7b96..ebd483b 100644 --- a/AFNetworking/UIImageView+AFNetworking.m +++ b/AFNetworking/UIImageView+AFNetworking.m @@ -84,7 +84,7 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"imageRequestOperat placeholderImage:(UIImage *)placeholderImage imageSize:(CGSize)imageSize options:(AFImageRequestOptions)options - block:(void (^)(UIImage *image))block + block:(void (^)(UIImage *image, BOOL cacheUsed))block { if (!url) { // stop loading image @@ -102,7 +102,7 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"imageRequestOperat self.image = cachedImage; if (block) { - block(cachedImage); + block(cachedImage, YES); } } else { self.image = placeholderImage; @@ -110,7 +110,7 @@ static NSString * const kUIImageViewImageRequestObjectKey = @"imageRequestOperat self.imageRequestOperation = [AFImageRequestOperation operationWithRequest:request imageSize:imageSize options:options success:^(UIImage *image) { if (self.imageRequestOperation && ![self.imageRequestOperation isCancelled]) { if (block) { - block(image); + block(image, NO); } if ([[request URL] isEqual:[[self.imageRequestOperation request] URL]]) {