GCD在主线程中执行任务
我有一个可能来自任何线程的callback。 当我得到这个callback,然后我想在主线程上执行一定的任务。
我是否需要检查我是否已经在主线程中 – 或者是否因为不执行此检查而被罚款?
dispatch_async(dispatch_get_main_queue(), ^{ // do work here });
不,你不需要检查你是否已经在主线程中。 通过将块分派到主队列中,您只是在主线程上调度要串行执行的块,这会在相应的运行循环运行时发生。
如果您已经在主线程中,则行为是相同的:块被调度,并在主线程的运行循环运行时执行。
对于上面描述的asynchronous调度情况,您不需要检查您是否在主线程上。 正如Bavarious所指出的那样,这只是排队等待在主线程上运行。
但是,如果您尝试使用dispatch_sync()
来执行上述操作,并且您的callback函数位于主线程上,那么您的应用程序将在此时发生死锁。 我在这里描述了这个问题,因为当从-performSelectorOnMainThread:
移动一些代码时,这个行为让我感到惊讶。 正如我在那里提到的,我创build了一个辅助函数:
void runOnMainQueueWithoutDeadlocking(void (^block)(void)) { if ([NSThread isMainThread]) { block(); } else { dispatch_sync(dispatch_get_main_queue(), block); } }
如果你所在的方法当前没有在主线程上,它将在主线程上同步运行一个程序段,如果是的话就直接执行内联程序段。 你可以使用如下的语法来使用它:
runOnMainQueueWithoutDeadlocking(^{ //Do stuff });
正如提到的其他答案,从主线程dispatch_async是好的。
但是,根据您的使用情况,有一个副作用,您可能会考虑一个缺点:由于该块计划在一个队列中,它将不会执行,直到控制回到运行循环,这将有延迟你的块的执行。
例如,
NSLog(@"before dispatch async"); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"inside dispatch async block main thread from main thread"); }); NSLog(@"after dispatch async");
将打印出来:
before dispatch async after dispatch async inside dispatch async block main thread from main thread
因为这个原因,如果你期望在外部NSLog之间执行块,dispatch_async不会帮你。
不,你不需要检查你是否在主线程中。 这里是你如何在Swift中做到这一点:
runThisInMainThread { () -> Void in runThisInMainThread { () -> Void in // No problem } } func runThisInMainThread(block: dispatch_block_t) { dispatch_async(dispatch_get_main_queue(), block) }
它包括在我的回购标准function,检查出来: https : //github.com/goktugyil/EZSwiftExtensions