swift - 使用 swift async/await api 的 GCD 串行队列方法?
问题描述
我正在采用新的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
,Swift 同步访问它的共享可变状态。如果模型是这样写的:
actor Model {
var data: Data
func updateModel(newData: Data) {
data = newData
}
}
这里的updateModel
函数是同步的,调用后它的执行是不间断的。因为 Model 是一个演员,Swift 限制你把它当作你从外部调用一个异步函数来对待。您必须这样做await
,这会导致您的活动线程暂停。
如果您想进行updateModel
异步,则其中的代码将始终是同步的,除非您通过调用 await 显式挂起它。多个调用的执行顺序updateModel
不是很确定。只要您不在updateModel
块内挂起,就可以确定它们是串行执行的。updateModel
在这种情况下,进行异步是没有用的。
推荐阅读
- c# - 在 NET Framework MVC 项目中的内部联接查询的视图中显示数据
- ruby-on-rails - Rails 如何在视图中传递 ID - MessagesController#create 中的 NameError
- swift - 如何在 Swift 中读取 3 个字节中的 19 位?
- java - 正则表达式在java中后跟另一个字符时删除一个字符
- applepay - ApplePay completeMerchantValidation 失败
- r - 我无法创建此变量
- c# - Unity C#:类型错误引用另一个脚本中的浮点数
- node.js - cypress 的最后一次测试显示所有断言
- r - 无法在 Linux Mint 19.3 中的 R 3.6.2 中安装 httr 包
- java - 警报对话框不显示任何内容