ios - global().async 中的 main.sync 是什么意思?

标签 ios swift grand-central-dispatch

在 Swift 中,我有时会使用这种模式。

DispatchQueue.global().async {
    // do stuff in background, concurrent thread

    DispatchQueue.main.sync {
        // update UI
    }
}

这个模式的目的很明确。在全局线程中进行耗时计算,使 UI 不被锁定,并在计算完成后在主线程中更新 UI。

如果没有什么可计算的怎么办?我刚刚在我的项目中发现了一个逻辑

//A
DispatchQueue.main.sync {
    // do something
}

崩溃但是

// B
DispatchQueue.global().async {
    DispatchQueue.main.sync {
        // do something
    }
}

不会崩溃。

它们有什么不同?情况 B 与此不同吗?

// C
DispatchQueue.main.async {
    // do something
}

还有一个问题。我知道主线程是串行队列,但如果我在多个 main.async 中运行多个代码块,它就像并发队列一样工作。

DispatchQueue.main.async {
    // do A
}

DispatchQueue.main.async {
    // do B
}

如果主线程真的是一个串行队列,它们怎么能同时运行呢?如果它只是一个时间片,那么除了主线程可以更新 UI 之外,它们与全局并发队列有何不同?

最佳答案

x.sync 表示调用队列将暂停并等待同步块(synchronized block)完成后继续。所以在你的例子中:

DispatchQueue.global().async {
    // yada yada something
    DispatchQueue.main.sync {
        // update UI
    }
    // this will happen only after 'update UI' has finished executing
}

通常你不需要sync 回到main,async 可能足够好并且更安全以避免死锁。除非是特殊情况,您需要等到 main 上的某些内容完成后再继续执行异步任务。

至于一个崩溃的例子 - 调用同步并定位当前队列是一个死锁(调用队列等待同步块(synchronized block)完成,但它不会启动,因为目标队列(相同)正忙于等待 sync 调用完成),这可能就是崩溃的原因。

至于使用异步在主队列上调度多个 block :它们不会并行运行 - 它们会一个接一个地发生。 也不要假设队列 == 线程。将多个 block 调度到同一个队列中,可能会创建系统允许的尽可能多的线程。只是主队列比较特殊,它使用主线程。

关于ios - global().async 中的 main.sync 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42772907/

相关文章:

ios - 为什么 Dispatch_group_notify 在不同的环境下工作不同?

ios - dispatch_group_wait 是否允许插队?

当应用程序处于事件状态时,iOS 推送通知无法在通知栏中显示?

ios - 在类型 'allowIDFACollection' Google Analytics iOS 的对象上找不到属性 '__strong id'

swift - Xcode 7-CocoaPod AlamoFire 及其他,导入到项目中但不在项目内部工作

ios - GCD队列不兼容类型错误

ios - collectionView 中的 CAShapelayer 在 reloadData() 上添加奇怪的动画

ios - 无法使用 HTTPS 连接到服务器

iOS:如何在框架内加载 xib

swift - 从何时捕获进度