From 3124db42cd6434f7c110251d2acd0b4ca377b38d Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 23 Apr 2012 20:58:14 -0700 Subject: [PATCH] Stashing first attempt to simplify dispatching --- AFNetworking/AFHTTPClient.m | 50 +++++++++++++-------- AFNetworking/AFHTTPRequestOperation.m | 60 +------------------------- AFNetworking/AFImageRequestOperation.m | 6 +-- AFNetworking/AFJSONRequestOperation.m | 4 +- 4 files changed, 39 insertions(+), 81 deletions(-) diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index 75a2876..5fcb4e1 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -41,6 +41,14 @@ NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"; +@interface AFBatchedOperation : NSBlockOperation +@property (readwrite, nonatomic, assign) dispatch_group_t dispatchGroup; +@end + +@implementation AFBatchedOperation +@synthesize dispatchGroup = _dispatchGroup; +@end + @interface AFMultipartFormData : NSObject { @private NSStringEncoding _stringEncoding; @@ -515,34 +523,40 @@ static void AFReachabilityCallback(SCNetworkReachabilityRef __unused target, SCN progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock { - dispatch_group_t dispatchGroup = dispatch_group_create(); + AFBatchedOperation *batchedOperation = [[[AFBatchedOperation alloc] init] autorelease]; + batchedOperation.dispatchGroup = dispatch_group_create(); + [batchedOperation addExecutionBlock:^{ + if (completionBlock) { + dispatch_group_notify(batchedOperation.dispatchGroup, dispatch_get_main_queue(), ^{ + completionBlock(operations); + }); + } + }]; NSPredicate *finishedOperationPredicate = [NSPredicate predicateWithFormat:@"isFinished == YES"]; for (AFHTTPRequestOperation *operation in operations) { AFCompletionBlock originalCompletionBlock = [[operation.completionBlock copy] autorelease]; - operation.dispatchGroup = dispatchGroup; operation.completionBlock = ^{ - if (progressBlock) { - dispatch_group_async(dispatchGroup, dispatch_get_main_queue(), ^{ + dispatch_group_async(batchedOperation.dispatchGroup, dispatch_get_main_queue(), ^{ + if (originalCompletionBlock) { + originalCompletionBlock(); + } + + if (progressBlock) { progressBlock([[operations filteredArrayUsingPredicate:finishedOperationPredicate] count], [operations count]); - }); - } - - if (originalCompletionBlock) { - originalCompletionBlock(); - } + } + + dispatch_group_leave(batchedOperation.dispatchGroup); + }); }; + + dispatch_group_enter(batchedOperation.dispatchGroup); + [batchedOperation addDependency:operation]; + [self enqueueHTTPRequestOperation:operation]; } - - if (completionBlock) { - dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{ - completionBlock(operations); - }); - } - - dispatch_release(dispatchGroup); + [self.operationQueue addOperation:batchedOperation]; } #pragma mark - diff --git a/AFNetworking/AFHTTPRequestOperation.m b/AFNetworking/AFHTTPRequestOperation.m index 0d399c7..3d61013 100644 --- a/AFNetworking/AFHTTPRequestOperation.m +++ b/AFNetworking/AFHTTPRequestOperation.m @@ -56,8 +56,7 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { @interface AFHTTPRequestOperation () @property (readwrite, nonatomic, retain) NSError *HTTPError; -@property (nonatomic) dispatch_once_t onceToken; -@property (atomic) dispatch_semaphore_t dispatchSemaphore; +@property (readwrite, nonatomic, assign) dispatch_semaphore_t dispatchSemaphore; @end @implementation AFHTTPRequestOperation @@ -67,10 +66,8 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { @synthesize successCallbackQueue = _successCallbackQueue; @synthesize failureCallbackQueue = _failureCallbackQueue; @synthesize dispatchGroup = _dispatchGroup; -@synthesize onceToken = _onceToken; @synthesize dispatchSemaphore = _dispatchSemaphore; - - (id)initWithRequest:(NSURLRequest *)request { self = [super initWithRequest:request]; if (!self) { @@ -98,17 +95,7 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { dispatch_release(_failureCallbackQueue); _failureCallbackQueue = NULL; } - - if (_dispatchGroup) { - dispatch_release(_dispatchGroup); - _dispatchGroup = NULL; - } - - if (_dispatchSemaphore) { - dispatch_release(_dispatchSemaphore); - _dispatchSemaphore = NULL; - } - + [super dealloc]; } @@ -176,49 +163,6 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) { } } -- (void)setDispatchGroup:(dispatch_group_t)dispatchGroup { - dispatch_semaphore_wait(self.dispatchSemaphore, DISPATCH_TIME_FOREVER); - if (dispatchGroup != _dispatchGroup) { - if (_dispatchGroup) { - dispatch_group_leave(_dispatchGroup); - dispatch_release(_dispatchGroup); - _dispatchGroup = NULL; - } - - if (dispatchGroup) { - dispatch_retain(dispatchGroup); - _dispatchGroup = dispatchGroup; - dispatch_group_enter(_dispatchGroup); - } - } - dispatch_semaphore_signal(self.dispatchSemaphore); -} - -- (dispatch_group_t)dispatchGroup { - dispatch_semaphore_wait(self.dispatchSemaphore, DISPATCH_TIME_FOREVER); - if(_dispatchGroup == NULL) { - _dispatchGroup = dispatch_group_create(); - dispatch_group_enter(_dispatchGroup); - } - dispatch_semaphore_signal(self.dispatchSemaphore); - return _dispatchGroup; -} - -- (void)setCompletionBlock:(void (^)(void))block { - __block AFHTTPRequestOperation *blockSelf = self; - dispatch_once_t *blockOnceToken = &_onceToken; - - [super setCompletionBlock:^{ - if(block) { - block(); - } - // Dispatch once is used to ensure that setting the block with this block will not cause multiple calls to 'dispatch_group_leave' - dispatch_once(blockOnceToken, ^{ - dispatch_group_leave(blockSelf.dispatchGroup); - }); - }]; -} - - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { diff --git a/AFNetworking/AFImageRequestOperation.m b/AFNetworking/AFImageRequestOperation.m index a27c5b6..3ff2fd0 100644 --- a/AFNetworking/AFImageRequestOperation.m +++ b/AFNetworking/AFImageRequestOperation.m @@ -236,10 +236,10 @@ static dispatch_queue_t image_request_operation_processing_queue() { return; } - dispatch_group_async(self.dispatchGroup, image_request_operation_processing_queue(), ^(void) { + dispatch_async(image_request_operation_processing_queue(), ^(void) { if (self.error) { if (failure) { - dispatch_group_async(self.dispatchGroup, self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{ failure(self, self.error); }); } @@ -253,7 +253,7 @@ static dispatch_queue_t image_request_operation_processing_queue() { image = self.responseImage; - dispatch_group_async(self.dispatchGroup, self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ success(self, image); }); } diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index dacacd9..2f513c9 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -130,7 +130,7 @@ static dispatch_queue_t json_request_operation_processing_queue() { }); } } else { - dispatch_group_async(self.dispatchGroup, json_request_operation_processing_queue(), ^(void) { + dispatch_async(json_request_operation_processing_queue(), ^{ id JSON = self.responseJSON; if (self.JSONError) { @@ -141,7 +141,7 @@ static dispatch_queue_t json_request_operation_processing_queue() { } } else { if (success) { - dispatch_group_async(self.dispatchGroup, self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ + dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{ success(self, JSON); }); }