【发布时间】:2021-09-28 22:34:47
【问题描述】:
我正在采用新的async/await Swift API。事情很好。
目前在我的应用程序中,我使用 GCD 串行队列作为管道来强制任务串行发生。
为了在应用程序中处理一些关键模型的数据,我使用了一个可从应用程序的任何位置访问的串行队列:
let modelQueue = DispatchQueue(label: "com.myapp.updatemodelqueue")
任何时候模型需要修改我派发到该队列的一些模型数据:
modelQueue.async {
// ... model updates
}
随着新的async/await 更改,我仍然想强制模型实际更新连续发生。因此,例如,当我从服务器导入新模型数据时,我想确保它们连续发生。
例如,我的模型中可能有一个如下所示的调用:
func updateCarModel() async {
let data = await getModelFromServer()
modelQueue.async {
// update model
}
}
由于modelQueue.async,使用该模式编写该函数不会等待模型更新更改。我不想使用modelQueue.sync 来避免死锁。
因此,在观看 WWDC 视频并查看文档后,我利用 withCheckedContinuation 实现了这种方式:
func updateCarModel() async {
let data = await getModelFromServer()
await withCheckedContinuation({ continuation in
modelQueue.async {
// update model
continuation.resume()
}
})
}
但是,据我了解,withCheckedContinuation 的真正目的是让我们逐步过渡到完全采用新的async/await Swift API。所以,这似乎不是我应该使用的最终方法。
然后我查看了actor,但我不确定这将如何让我序列化我想在应用程序周围序列化的任何模型工作,就像我对上面所示的静态队列所做的那样。
那么,我怎样才能像以前一样在应用程序周围强制执行模型更新 serially,同时完全采用新的 await/async swift API 而不使用 withCheckedContinuation?
【问题讨论】:
-
Actor 正是这样做的,允许您在 async-await 范式中对某些模型对象执行异步更新,但无需您手动与串行队列(或任何其他普通同步机制)同步。它会为您进行同步。
-
是的,我同意。我只是想了解我将如何正确地构建事物。是全球演员吗?队列的好处是,我可以从应用程序的任何地方调度它并完成。所以,这就是我研究演员的原因,但不确定如何实际解决它以提供与应用程序范围的串行队列类似的方法......
-
使用actor的问题是你只能在actor上使用非异步函数来创建串行队列。如果您使用标记为 async 的函数,则其他代码可以在暂停期间运行,这使其成为非串行的。
-
我也有类似的问题。在幕后的并发演讲中,他们有一个使用 Actor 代替串行数据库队列的示例。但他们指出,Actor 调用不再有发生前/FIFO 保证,这与串行队列(调度或操作)不同。
标签: swift async-await