Mal*_*loc 0 concurrency task async-await swift
曾几何时,在 Async/Await 出现之前,我们使用 URLSession dataTask 向服务器发出简单的请求。回调不会在主线程上自动调用,我们必须手动分派到主线程才能执行一些 UI 工作。例子:
DispatchQueue.main.async {
// UI work
}
Run Code Online (Sandbox Code Playgroud)
忽略这一点将导致应用程序崩溃,因为我们尝试在与主队列不同的队列上更新 UI。
现在有了 Async/Await ,事情变得更容易了。我们仍然必须使用 调度到主队列MainActor。
await MainActor.run {
// UI work
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,即使我不使用MainActor任务中的代码似乎也在主线程上运行,并且更新 UI 似乎是安全的。
Task {
let api = API(apiConfig: apiConfig)
do {
let posts = try await api.getPosts() // Checked this and the code of getPosts is running on another thread.
self.posts = posts
self.tableView.reloadData()
print(Thread.current.description)
} catch {
// Handle error
}
}
Run Code Online (Sandbox Code Playgroud)
我预计我的代码会导致崩溃,因为理论上我试图更新表视图而不是从主线程,但日志显示我位于主线程上。日志print如下:
<_NSMainThread: 0x600003bb02c0>{number = 1, name = main}
Run Code Online (Sandbox Code Playgroud)
这是否意味着在执行 UI 操作之前无需检查我们所在的队列?
关于Task {\xe2\x80\xa6},这将 \xe2\x80\x9c 创建一个在当前 actor\xe2\x80\x9d 上运行的非结构化任务(请参阅Swift 并发:非结构化并发)。这是从同步上下文启动异步任务的好方法。而且,如果由主要演员调用,这个Task也将由主要演员负责。
在您的情况下,我会将模型更新和 UI 刷新移至标记为在主要参与者上运行的函数:
\n@MainActor\nfunc update(with posts: [Post]) async {\n self.posts = posts \n tableView.reloadData()\n}\nRun Code Online (Sandbox Code Playgroud)\n然后你可以这样做:
\nTask {\n let api = API(apiConfig: apiConfig)\n \n do {\n let posts = try await api.getPosts() // Checked this and the code of getPosts is running on another thread.\n self.update(with: posts)\n } catch {\n // Handle error\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n它的美妙之处在于,如果你\xe2\x80\x99还没有成为主角,编译器会告诉你必须使用await该update方法。编译器会告诉你是否需要await。
如果您还没有\xe2\x80\x99 看过它,我可能建议观看 WWDC 2021 视频Swift 并发:更新示例应用程序。它提供了许多有关将代码转换为 Swift 并发的实用技巧,但特别是在 24:16 ,他们介绍了从DispatchQueue.main.async {\xe2\x80\xa6}Swift 并发的演变(例如,最初建议直观的MainActor.run {\xe2\x80\xa6}步骤,但在接下来的几分钟内,说明为什么即使这样做也是不必要的) ,但也讨论了您可能想要使用此功能的罕见情况)。
顺便说一句,在 Swift 并发中,光看Thread.current是不可靠的。因此,这种做法可能会在未来的编译器版本中被禁止。
如果您观看 WWDC 2021 Swift 并发:幕后花絮,您将了解支撑 Swift 并发的各种机制,并且您将更好地理解为什么查看Thread.current可能会导致各种不正确的结论。
| 归档时间: |
|
| 查看次数: |
999 次 |
| 最近记录: |