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

Rya*_*yan 15 grand-central-dispatch ios swift

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

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

    DispatchQueue.main.sync {
        // update UI
    }
}
Run Code Online (Sandbox Code Playgroud)

这种模式的目的很明确.在全局线程中进行耗时的计算,因此UI未被锁定,并且在计算完成后更新主线程中的UI.

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

//A
DispatchQueue.main.sync {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

崩溃但是

// B
DispatchQueue.global().async {
    DispatchQueue.main.sync {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

没有崩溃.

他们有什么不同?案例B是否与此不同?

// C
DispatchQueue.main.async {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

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

DispatchQueue.main.async {
    // do A
}

DispatchQueue.main.async {
    // do B
}
Run Code Online (Sandbox Code Playgroud)

如果主线程实际上是一个串行队列,它们如何同时运行?如果它只是一个时间切片而不是它们与全局并发队列的不同而不是主线程可以更新UI?

Min*_*gas 18

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

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

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

至于一个示例崩溃 - 调用同步和目标当前队列是一个死锁(调用队列等待同步块完成,但它没有启动,因为目标队列(相同)忙于等待sync调用完成)这可能是为什么碰撞.

至于使用异步调度主队列上的多个块:它们不会并行运行 - 它们将一个接一个地发生.也不要假设queue == thread.将多个块调度到同一队列可能会创建与系统允许的一样多的线程.只是主队列是特殊的,它利用主线程.