Answers:
不,您不需要检查您是否已经在主线程上。通过将块分配到主队列,您只是在调度要在主线程上串行执行的块,这是在运行相应的运行循环时发生的。
如果您已经在主线程上,则其行为是相同的:该块已调度,并在运行主线程的运行循环时执行。
对于上面描述的异步分派情况,不需要检查是否在主线程上。正如Bavarious所指出的,这将简单地排队等待在主线程上运行。
但是,如果尝试使用a进行上述操作,dispatch_sync()
并且回调位于主线程上,则此时应用程序将死锁。我在此处的答案中对此进行了描述,因为从移出某些代码时,这种行为使我感到惊讶-performSelectorOnMainThread:
。正如我在此处提到的,我创建了一个辅助函数:
void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
如果您所使用的方法当前不在主线程上,则它将在主线程上同步运行一个块,如果在内部线程上,则仅直接内联执行该块。您可以采用以下语法来使用此语法:
runOnMainQueueWithoutDeadlocking(^{
//Do stuff
});
dispatch_set_specific()
在您描述的情况下是否有帮助:stackoverflow.com/a/12806754/19679。
正如提到的其他答案一样,来自主线程的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)
}
它作为标准功能包含在我的仓库中,请查看:https : //github.com/goktugyil/EZSwiftExtensions