diff --git a/AFNetworking/AFHTTPRequestOperation.h b/AFNetworking/AFHTTPRequestOperation.h index 350b64a..ea6bfd0 100644 --- a/AFNetworking/AFHTTPRequestOperation.h +++ b/AFNetworking/AFHTTPRequestOperation.h @@ -31,6 +31,8 @@ NSIndexSet *_acceptableStatusCodes; NSSet *_acceptableContentTypes; NSError *_HTTPError; + dispatch_queue_t _successCallbackQueue; + dispatch_queue_t _failureCallbackQueue; } ///---------------------------------------------- @@ -71,6 +73,17 @@ */ @property (readonly) BOOL hasAcceptableContentType; +/** + The callback dispatch queue on success. If this is NULL (default), the main queue is used. + */ +@property (nonatomic) dispatch_queue_t successCallbackQueue; + +/** + The callback dispatch queue on failure. If this is NULL (default), the main queue is used. + */ +@property (nonatomic) dispatch_queue_t failureCallbackQueue; + + /** A Boolean value determining whether or not the class can process the specified request. For example, `AFJSONRequestOperation` may check to make sure the content type was `application/json` or the URL path extension was `.json`. @@ -94,3 +107,18 @@ failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; @end + + +@interface AFHTTPRequestOperation (AFInternal) + +/** + Executes the successBlock on the corresponding successCallbackQueue. + */ +- (void)dispatchSuccessBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))successBlock responseObject:(id)responseObject; + +/** + Executes the failureBlock on the corresponding failureCallbackQueue. + */ +- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock; + +@end \ No newline at end of file diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 38802c1..591c56e 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -30,6 +30,9 @@ @synthesize acceptableStatusCodes = _acceptableStatusCodes; @synthesize acceptableContentTypes = _acceptableContentTypes; @synthesize HTTPError = _HTTPError; +@synthesize successCallbackQueue = _successCallbackQueue; +@synthesize failureCallbackQueue = _failureCallbackQueue; + - (id)initWithRequest:(NSURLRequest *)request { self = [super initWithRequest:request]; @@ -46,6 +49,8 @@ [_acceptableStatusCodes release]; [_acceptableContentTypes release]; [_HTTPError release]; + if (_successCallbackQueue) { dispatch_release(_successCallbackQueue), _successCallbackQueue=NULL;} + if (_failureCallbackQueue) { dispatch_release(_failureCallbackQueue), _failureCallbackQueue=NULL;} [super dealloc]; } @@ -85,6 +90,34 @@ return !self.acceptableContentTypes || [self.acceptableContentTypes containsObject:[self.response MIMEType]]; } +- (void)setSuccessCallbackQueue:(dispatch_queue_t)successCallbackQueue { + if (successCallbackQueue != _successCallbackQueue) { + + if (_successCallbackQueue) { + dispatch_release(_successCallbackQueue); + } + + if (successCallbackQueue) { + dispatch_retain(successCallbackQueue); + _successCallbackQueue = successCallbackQueue; + } + } +} + +- (void)setFailureCallbackQueue:(dispatch_queue_t)failureCallbackQueue { + if (failureCallbackQueue != _failureCallbackQueue) { + + if (_failureCallbackQueue) { + dispatch_release(_failureCallbackQueue); + } + + if (failureCallbackQueue) { + dispatch_retain(failureCallbackQueue); + _failureCallbackQueue = failureCallbackQueue; + } + } +} + - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { @@ -94,17 +127,9 @@ } if (self.error) { - if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure]; } else { - if (success) { - dispatch_async(dispatch_get_main_queue(), ^{ - success(self, self.responseData); - }); - } + [self dispatchSuccessBlock:success responseObject:self.responseString]; } }; } @@ -113,6 +138,24 @@ + (BOOL)canProcessRequest:(NSURLRequest *)request { return YES; -} +} + +#pragma mark - AFInternal + +- (void)dispatchSuccessBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))successBlock responseObject:(id)responseObject { + if (successBlock) { + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + successBlock(self, responseObject); + }); + } +} + +- (void)dispatchFailureBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock { + if (failureBlock) { + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + failureBlock(self, self.error); + }); + } +} @end diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index f28d497..f732a3c 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -230,17 +230,9 @@ static dispatch_queue_t image_request_operation_processing_queue() { dispatch_async(image_request_operation_processing_queue(), ^(void) { if (self.error) { - if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - failure(self, self.error); - }); - } - } else { - if (success) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - success(self, self.responseImage); - }); - } + [self dispatchFailureBlock:failure]; + } else { + [self dispatchSuccessBlock:success responseObject:self.responseImage]; } }); }; diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index 5c651de..6d39413 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -124,26 +124,16 @@ static dispatch_queue_t json_request_operation_processing_queue() { } if (self.error) { - if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure]; } else { dispatch_async(json_request_operation_processing_queue(), ^(void) { id JSON = self.responseJSON; - dispatch_async(dispatch_get_main_queue(), ^(void) { - if (self.JSONError) { - if (failure) { - failure(self, self.JSONError); - } - } else { - if (success) { - success(self, JSON); - } - } - }); + if (self.JSONError) { + [self dispatchFailureBlock:failure]; + } else { + [self dispatchSuccessBlock:success responseObject:JSON]; + } }); } }; diff --git a/AFNetworking/AFPropertyListRequestOperation.m b/AFNetworking/AFPropertyListRequestOperation.m index bb7a41b..d294cd2 100644 --- a/AFNetworking/AFPropertyListRequestOperation.m +++ b/AFNetworking/AFPropertyListRequestOperation.m @@ -124,26 +124,16 @@ static dispatch_queue_t property_list_request_operation_processing_queue() { } if (self.error) { - if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure]; } else { dispatch_async(property_list_request_operation_processing_queue(), ^(void) { id propertyList = self.responsePropertyList; - - dispatch_async(dispatch_get_main_queue(), ^(void) { - if (self.propertyListError) { - if (failure) { - failure(self, self.propertyListError); - } - } else { - if (success) { - success(self, propertyList); - } - } - }); + + if (self.propertyListError) { + [self dispatchFailureBlock:failure]; + }else { + [self dispatchSuccessBlock:success responseObject:propertyList]; + } }); } }; diff --git a/AFNetworking/AFXMLRequestOperation.m b/AFNetworking/AFXMLRequestOperation.m index b6b3a2b..7b50fd6 100644 --- a/AFNetworking/AFXMLRequestOperation.m +++ b/AFNetworking/AFXMLRequestOperation.m @@ -187,15 +187,9 @@ static dispatch_queue_t xml_request_operation_processing_queue() { } if (self.error) { - if (failure) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - failure(self, self.error); - }); - } + [self dispatchFailureBlock:failure]; } else { - if (success) { - success(self, self.responseXMLParser); - } + [self dispatchSuccessBlock:success responseObject:self.responseXMLParser]; } }; }