在 Objective C 中调度块的执行

Posted

技术标签:

【中文标题】在 Objective C 中调度块的执行【英文标题】:Scheduling execution of blocks in Objective C 【发布时间】:2021-10-02 20:32:39 【问题描述】:

我正在目标 C 中创建一个应用程序,其中有两个线程:

    主线程,从睡眠中唤醒并被其上的模块异步调用 回调块(线程)的执行是异步的,并且依赖于发送通知的外部模块“M”。

在我的主线程上,我想在开始执行任务之前等待回调进来。所以,我尝试在主线程上使用dispatch_group_enterdispatch_group_wait(FOREVER),同时在回调线程上调用dispatch_group_leave。这确保了当主线程第一个执行时,事情会按预期发生,即主线程等待回调进入并在执行其任务之前解除阻塞。

但是,我看到了一种竞争情况,回调块有时会首先被调用并停留在dispatch_group_leave(因为此时主线程尚未调用dispatch_group_enter

我可以为此目的使用不同的 GCD 构造吗?

【问题讨论】:

为什么这么复杂?在 GCD 中,您通常不会考虑线程。它们被抽象在队列下面。您通常会为您的“主线程”创建一个队列(这不是一个很好用的术语,因为“主线程”在 ios 中具有特定含义,所以我将其称为 WorkQueue。当然,如果您在谈论阻塞主线程,那么这是一个非常糟糕的主意)。当回调代码被执行时,它可以简单地将所需的任务分派到 WorkQueue 上。 GCD 会找到一个合适的线程来执行工作。这个任务没有理由“睡觉”;它要么正在执行,要么没有。 【参考方案1】:

“主线程”是处理 UI、系统事件、通知等的线程。我们从不阻塞该线程。阻止它会导致可怕的用户体验,应用程序似乎会冻结,您的应用程序甚至可能被“看门狗”进程终止,这会杀死它认为已冻结的应用程序。在某些情况下,应用会死锁。

所以,如果你真的是指“主线程”,那么答案是你永远不会在那个线程上“等待”(或以其他方式阻止它)。该模式是让您的后台线程做它需要做的事情,然后使用 GCD 将模型/UI 更新分派回主线程(或提交您的通知并让主线程处理它)。

如果您想要一个在后台进程正在进行时不允许用户与 UI 交互的 UX,您可以在 UI 中显示一些内容来明确这一点。一种常见的模式是覆盖整个视图的调暗/模糊视图,通常使用UIActivityIndicatorView(即微调器),并且当分派到后台队列的任务完成时(或让通知处理程序执行此操作),您'然后删除那个变暗/模糊的视图和微调器并相应地更新 UI。

但你永远不会因为等待而阻塞主线程。

【讨论】:

以上是关于在 Objective C 中调度块的执行的主要内容,如果未能解决你的问题,请参考以下文章

Programming with Objective-C

objective-c数组

求一份儿C语言优先级调度算法要求如下

如何在Objective C中将对象序列化为JSON? [复制]

第一章-了解Objective - C语言的起源

Objective C 自动释放