微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GCD在主线程中执行任务

如何解决GCD在主线程中执行任务

| 我有一个可能来自任何线程的回调。当我收到此回调时,我想在主线程上执行某些任务。 我需要检查我是否已经在主线程上吗?或者通过调用下面的代码不执行此检查是否有任何损失?
dispatch_async(dispatch_get_main_queue(),^{
   // do work here
});
    

解决方法

不,您不需要检查您是否已经在主线程上。通过将块分配到主队列,您只需调度要在主线程上串行执行的块,这将在运行相应的运行循环时发生。 如果您已经在主线程上,则行为是相同的:该块已调度,并在运行主线程的运行循环时执行。     ,对于上面描述的异步调度情况,您不需要检查自己是否在主线程上。正如Bavarious所指出的,这将简单地排队等待在主线程上运行。 但是,如果尝试使用ѭ1进行上述操作,并且回调位于主线程上,则此时应用程序将死锁。我在这里的答案中对此进行了描述,因为当从
-performSelectorOnMainThread:
中移出某些代码时,这种行为使我感到惊讶。正如我在此处提到的,我创建了一个辅助函数:
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)
}
它作为标准功能包含在我的仓库中,请查看:https://github.com/goktugyil/EZSwiftExtensions     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。