Created
February 18, 2015 00:45
-
-
Save jcayzac/7e6d39471ec9d0fa1b24 to your computer and use it in GitHub Desktop.
Have a block operation depend on a network operation (AFNetworking)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The problem: AFNetworking calls the operation's completion block asynchronously, so it breaks `-[NSOperation addDependency:]` order as the dependent is started *before* the dependency's completion block. | |
dispatch_semaphore_t sem = dispatch_semaphore_create(0); | |
__block NSOperation* blockOperation = nil; | |
void (^networkOperationHandler)(NSOperation *, id) = ^(NSOperation *operation, id __unused unused) { | |
if (operation.cancelled) | |
{ | |
NSLog(@"networkOperation: networkOperation cancelled!"); | |
[blockOperation cancel]; | |
} | |
NSLog(@"networkOperation: networkOperation signalling blockOperation"); | |
dispatch_semaphore_signal(sem); | |
NSLog(@"networkOperation: networkOperation finished"); | |
}; | |
NSMutableURLRequest *request = [_net.requestSerializer requestWithMethod:@"GET" URLString:@"http://www.google.com/" parameters:nil error:0]; | |
NSOperation *networkOperation = [_net HTTPRequestOperationWithRequest:request | |
success:networkOperationHandler | |
failure:networkOperationHandler]; | |
blockOperation = [NSBlockOperation blockOperationWithBlock:^{ | |
NSLog(@"blockOperation: started"); | |
if (sem) | |
{ | |
NSLog(@"blockOperation: waiting for networkOperation"); | |
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); | |
NSLog(@"blockOperation: networkOperation finished"); | |
} | |
if (blockOperation.cancelled) | |
{ | |
NSLog(@"blockOperation: blockOperation cancelled!"); | |
return; | |
} | |
NSLog(@"blockOperation: blockOperation finished"); | |
}]; | |
[blockOperation addDependency:networkOperation]; | |
[_net.operationQueue addOperations:@[networkOperation, blockOperation] waitUntilFinished:NO]; | |
return networkOperation; | |
... | |
// - blockOperation's block waits for the network operation to have called its completion handler | |
// - cancelling networkOperation properly cancels the chain: | |
[networkOperation cancel]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment