I'm a big fan of blocks, but have not used them for concurrency. After some googling, I pieced together this idea to hide everything I learned in one place. The goal is to execute a block in the background, and when it's finished, execute another block (like UIView animation)...
- (NSOperation *)executeBlock:(void (^)(void))block completion:(void (^)(BOOL finished))completion {
    NSOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:block];
    NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
        completion(blockOperation.isFinished);
    }];
    [completionOperation addDependency:blockOperation];
    [[NSOperationQueue mainQueue] addOperation:completionOperation];    
    NSOperationQueue *backgroundOperationQueue = [[NSOperationQueue alloc] init];
    [backgroundOperationQueue addOperation:blockOperation];
    return blockOperation;
}
- (void)testIt {
    NSMutableString *string = [NSMutableString stringWithString:@"tea"];
    NSString *otherString = @"for";
    NSOperation *operation = [self executeBlock:^{
        NSString *yetAnother = @"two";
        [string appendFormat:@" %@ %@", otherString, yetAnother];
    } completion:^(BOOL finished) {
        // this logs "tea for two"
        NSLog(@"%@", string);
    }];
    NSLog(@"keep this operation so we can cancel it: %@", operation);
}
My questions are:
- It works when I run it, but am I missing anything ... hidden land mine? I haven't tested cancellation (because I haven't invented a long operation), but does that look like it will work?
- I'm concerned that I need to qualify my declaration of backgroundOperation so that I can refer to it in the completion block. The compiler doesn't complain, but is there a retain cycle lurking there?
- If the "string" were an ivar, what would happen if I key-value observed it while the block was running? Or setup a timer on the main thread and periodically logged it? Would I be able to see progress? Would I declare it atomic?
- If this works as I expect, then it seems like a good way to hide all the details and get concurrency. Why didn't Apple write this for me? Am I missing something important?
Thanks.
 
     
     
     
    