在 iOS GCD 中调用 DispatchQueue.main.async 的成本

Cost of calling DispatchQueue.main.async in iOS GCD

我最近找到了一些代码示例

func stpDispatchToMainThreadIfNecessary(_ block: @escaping () -> Void) {
    if Thread.isMainThread {
        block()
    } else {
        DispatchQueue.main.async(execute: block)
    }
}

看起来如果我们将所有块都包装在 DispatchQueue.main.async 中,无论它是哪个线程,它在技术上都可以工作。
问题是为什么要检查主线程?
它是否添加了一些优化?如果是 - 在哪里阅读它以及如何对其进行基准测试?

async 调度的重要一点。

如果从主线程调用stpDispatchToMainThreadIfNecessary,则block同步执行,而如果从后台线程调用func,由于async(execute:)调用,block异步执行。

这意味着当从主线程调用时,由于同步执行,block 将比它也包含在 Dispatch 异步调用中更快地执行。

您可以将 async(execute:) 更改为 sync(execute:),与简单地调用 block() 相比,这在主线程的情况下不会导致延迟,但是,您不应该调度从后台线程同步到主线程,因为这可能会冻结 UI.

因此检查 func 是否从主线程调用并在这种情况下同步执行 block,同时将其从任何其他线程异步分派到主线程确保没有不必要的主线程阻塞从另一个线程调用 func 时线程,但从主线程调用 func 时也没有不必要的延迟。