Invoke model method with block that will run on the main thread

前端 未结 4 2033
野性不改
野性不改 2020-12-13 16:36

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

相关标签:
4条回答
  • 2020-12-13 16:57

    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 );
            });
        });
    }
    
    0 讨论(0)
  • 2020-12-13 17:12

    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];
    
    0 讨论(0)
  • 2020-12-13 17:13

    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.

    0 讨论(0)
  • 2020-12-13 17:20

    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];
    
    0 讨论(0)
提交回复
热议问题