使用将在主线程上运行的块调用模型方法

时间:2011-02-09 11:41:41

标签: iphone objective-c ipad

我最新应用程序架构的核心原则之一是,我将在应用程序模型上调用方法,这些方法将是异步并接受失败和成功场景块。

即,UI使用2个块调用模型方法,一个用于成功,一个用于失败。

这很好,因为保留了原始调用的上下文,但是在后台线程上调用了块本身。无论如何在主线程上调用一个块??

希望我已经把它说好了,如果没有,基本上,我的模型方法是异步的,立即返回并创建一个运行op的新线程。一旦op返回,我将调用一个块,它将对返回的数据进行后处理,然后我需要为UI内部调用的成功场景调用块。但是,UI中定义的成功和失败场景块应该在主线程中调用,因为我需要与UI元素进行交互,这只能在我认为的主线程上完成。

非常感谢

4 个答案:

答案 0 :(得分:36)

这样的事情可能就是你所追求的:

- (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 );
        });
    });
}

答案 1 :(得分:10)

如果您使用的是GCD,则可以使用“获取主队列”:

dispatch_queue_t dispatch_get_main_queue()

在异步调度中调用此方法。即。

dispatch_async(dispatch_get_main_queue(), ^{
  /* Do somthing here with UIKit here */
})

上面的示例块可以在异步后台队列中运行,示例代码会将UI工作发送到主线程。

答案 2 :(得分:6)

类似的方法也适用于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];

答案 3 :(得分:5)

NSObject有一个方法:

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

创建一个方法,该方法在一个方便的类中使用NSDictionary参数(如app appate或singleton对象),将块及其参数打包成NSDictionary或NSArray,然后调用

[target performSelectorOnMainThread:@selector(doItSelector) withObject:blockAndParameters waitUntilDone:waitOrNot];