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

kri*_*son 8 iphone objective-c ipad

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

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

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

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

非常感谢

Jim*_*vey 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 );
        });
    });
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*Cat 10

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

dispatch_queue_t dispatch_get_main_queue()
Run Code Online (Sandbox Code Playgroud)

在异步调度中调用它.即

dispatch_async(dispatch_get_main_queue(), ^{
  /* Do somthing here with UIKit here */
})
Run Code Online (Sandbox Code Playgroud)

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


Gur*_*rse 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];
Run Code Online (Sandbox Code Playgroud)


Bog*_*tyr 5

NSObject有一个方法:

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
Run Code Online (Sandbox Code Playgroud)

创建需要的NSDictionary参数便利类中的方法,将永远存在(如您的应用程序委托,或一个单独的对象),包了块及其参数成的NSDictionary的NSArray或和呼叫

[target performSelectorOnMainThread:@selector(doItSelector) withObject:blockAndParameters waitUntilDone:waitOrNot];
Run Code Online (Sandbox Code Playgroud)