Skip to content

Instantly share code, notes, and snippets.

@jcayzac
Created February 18, 2015 00:45
Show Gist options
  • Save jcayzac/7e6d39471ec9d0fa1b24 to your computer and use it in GitHub Desktop.
Save jcayzac/7e6d39471ec9d0fa1b24 to your computer and use it in GitHub Desktop.
Have a block operation depend on a network operation (AFNetworking)
// 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