我在objective C中创建了一个应用程序,我有两个线程:
- 主线程,从睡眠中被唤醒并被上面的模块异步调用
- 回调块(线程),它的执行是异步的,并且依赖于外部模块"发送通知
在我的主线程上,我想在开始执行任务之前等待回调进来。因此,我尝试在主线程上使用dispatch_group_enter
和dispatch_group_wait(FOREVER)
,同时在回调线程上调用dispatch_group_leave
。这确保了当主线程是第一个执行时,事情按照预期发生,即主线程等待回调进入并在执行任务之前解除阻塞。
然而,我看到一个竞争条件,其中回调块有时首先被调用,并被卡住在dispatch_group_leave
(因为在这一点上主线程还没有调用到dispatch_group_enter
)。
是否有一个不同的GCD结构我可以使用这个目的?
主线程是处理UI,系统事件,通知等的线程。我们从不阻塞那个线程。阻止它会导致糟糕的用户体验,应用看起来会被冻结,你的应用甚至可能被"看门狗"进程终止,它会杀死那些被冻结的应用。在某些情况下,应用程序会死锁。
所以,如果你真的是指"主线程",那么答案是你永远不会在那个线程上"等待"(或者阻塞它)。模式是让你的后台线程做它需要做的事情,然后用GCD将模型/UI更新分派回主线程(或者提交你的通知,让主线程处理它)。
如果你想要一个用户体验,在这个后台进程正在进行的时候,用户不允许与UI交互,你应该在你的UI中呈现一些东西来明确这一点。一个常见的模式是一个调光/模糊视图,覆盖整个视图,通常与UIActivityIndicatorView
(即,一个微调器),当任务分派到后台队列完成(或有通知处理程序做),然后你会删除调光/模糊视图和微调器,并相应地更新UI。
但是你永远不能通过等待来阻塞主线程。