one of the central tenets of the architecture of my latest app is that I\'m going to call methods on the app\'s model which will be async and accept failure and success scen
Something like this is probably what you're after:
- (void) doSomethingWhichTakesAgesWithArg: (id) theArg
resultHandler: (void (^)(BOOL, id, NSError *)) handler
{
// run in the background, on the default priority queue
dispatch_async( dispatch_get_global_queue(0, 0), ^{
id someVar = [theArg computeSomething];
NSError * anError = nil;
[someVar transmuteSomehowUsing: self error: &anError];
// call the result handler block on the main queue (i.e. main thread)
dispatch_async( dispatch_get_main_queue(), ^{
// running synchronously on the main thread now -- call the handler
handler( (error == nil), theArg, anError );
});
});
}
Similar approach works also with NSOperationQueue
:
NSBlockOperation *aOperation = [NSBlockOperation blockOperationWithBlock:^
{
if ( status == FAILURE )
{
// Show alert -> make sure it runs on the main thread
[[NSOperationQueue mainQueue] addOperationWithBlock:^
{
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Alert" message:@"Your action failed!" delegate:nil
cancelButtonTitle:@"Ok" otherButtonTitles:nil] autorelease];
[alert show];
}];
}
}];
// myAsyncOperationQueue is created somewhere else
[myAsyncOperationQueue addOperation:aOperation];
If you are using GCD, you can use the "get main queue":
dispatch_queue_t dispatch_get_main_queue()
Call this inside an async dispatch. i.e.
dispatch_async(dispatch_get_main_queue(), ^{
/* Do somthing here with UIKit here */
})
The example block above could be running in an async background queue and the example code would send the UI work off to the main thread.
NSObject has a method:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
Create a method that takes a NSDictionary parameter in a convenient class that will always be around (like your app delegate, or a singleton object), package up the block and its parameters into a NSDictionary or NSArray, and call
[target performSelectorOnMainThread:@selector(doItSelector) withObject:blockAndParameters waitUntilDone:waitOrNot];