Egi*_*gil 228 objective-c grand-central-dispatch
我有一个可能来自任何线程的回调.当我得到这个回调,然后我想在主线程上执行某个任务.
我是否需要检查我是否已经在主线程上 - 或者是否因为没有执行此检查而遭受任何惩罚?请调用下面的代码?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Run Code Online (Sandbox Code Playgroud)
小智 143
不,您不需要检查您是否已经在主线程上.通过将块分派给主队列,您只是在主线程上调度要串行执行的块,这在运行相应的运行循环时发生.
如果您已经在主线程上,则行为是相同的:块被调度,并在运行主线程的运行循环时执行.
Bra*_*son 99
对于上面描述的异步调度情况,您不需要检查是否在主线程上.正如Bavarious所说,这将简单地排队等候在主线程上运行.
但是,如果您尝试使用a执行上述操作dispatch_sync()并且您的回调位于主线程上,那么您的应用程序将在此时死锁.我在这里的答案中对此进行了描述,因为在移动某些代码时,这种行为让我感到惊讶-performSelectorOnMainThread:.正如我在那里提到的,我创建了一个辅助函数:
void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你所在的方法当前不在主线程上,它将在主线程上同步运行一个块,如果是,则只执行块内联.您可以使用以下语法来使用它:
runOnMainQueueWithoutDeadlocking(^{
//Do stuff
});
Run Code Online (Sandbox Code Playgroud)
Mic*_*nen 50
正如其他提到的答案,主线程中的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");
Run Code Online (Sandbox Code Playgroud)
将打印出来:
before dispatch async
after dispatch async
inside dispatch async block main thread from main thread
Run Code Online (Sandbox Code Playgroud)
出于这个原因,如果您希望块在外部NSLog之间执行,dispatch_async将无法帮助您.
| 归档时间: |
|
| 查看次数: |
113952 次 |
| 最近记录: |