使用 swift async/await api 的 GCD 串行队列类似方法?

zum*_*zum 12 async-await swift

我正在采用新的async/awaitSwift API。事情进展顺利。目前,在我的应用程序中,我使用 GCD 串行队列作为管道来强制任务连续发生。

为了操作应用程序中某些关键模型的数据,我使用可从应用程序中的任何位置访问的串行队列:

let modelQueue = DispatchQueue(label: "com.myapp.updatemodelqueue")
Run Code Online (Sandbox Code Playgroud)

每当模型需要修改一些模型数据时,我都会分派到该队列:

modelQueue.async {
        // ... model updates
}
Run Code Online (Sandbox Code Playgroud)

通过我所做的新async/await更改,我仍然希望强制模型实际更新连续发生。因此,例如,当我从服务器导入新模型数据时,我想确保它们连续发生。

例如,我的模型中可能有一个如下所示的调用:

func updateCarModel() async {
    
    let data = await getModelFromServer()
    
    modelQueue.async {
        
        // update model
        
    }

}
Run Code Online (Sandbox Code Playgroud)

然而,使用该模式编写该函数不会等待模型更新更改,因为modelQueue.async. 我不想使用modelQueue.sync以避免死锁。

因此,在观看 WWDC 视频并查看文档后,我利用以下方式实现了withCheckedContinuation

func updateCarModel() async {
    
    let data = await getModelFromServer()
    
    
    await withCheckedContinuation({ continuation in
        modelQueue.async {
            
            // update model
         
            continuation.resume()
        }
    })
    
}
Run Code Online (Sandbox Code Playgroud)

然而,据我了解,withCheckedContinuation真正的目的是让我们逐步过渡以完全采用新的async/awaitSwift API。所以,这似乎不是我应该使用的最终方法。

然后我查看了actor,但我不确定这将如何允许我序列化我想要在应用程序周围序列化的任何模型工作,就像我对上面所示的静态队列所做的那样。

那么,如何在应用程序周围强制执行我的模型,serially像以前一样进行模型更新,同时完全采用新的等待/异步 swift API,而不使用withCheckedContinuation

Aru*_*ddy 3

通过将模型设为actor,Swift 可以同步对其共享可变状态的访问。如果模型是这样写的:

actor Model {
    var data: Data
    
    func updateModel(newData: Data) {
        data = newData
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的函数updateModel是同步的,调用后它的执行不会中断。由于 Model 是一个参与者,Swift 限制您将其视为从外部调用异步函数。您必须这样做await,这会导致您的活动线程挂起。

如果您想要updateModel异步,则其中的代码将始终是同步的,除非您通过调用await 显式挂起它。多个调用的执行顺序updateModel不是很确定。只要您不在updateModel块内挂起,就可以肯定它们会串行执行。在这种情况下,进行异步是没有用的updateModel