如何在 MainActor 中使用 URLSession
How to use URLSession in MainActor
我有一个 ViewModel
与 @MainActor
隔离,我假设这个 ViewModel
class 的每个部分都应该 运行 在主要演员身上(主线程),对吧?
那么问题来了,URLSession.shared.data
的异步调用呢?
它也在 main thread
上 运行 吗?这不是一个糟糕的做法吗?
@MainActor
class ViewModel {
@Published var name: String = ""
func fetchName() async {
guard let (data, _) = try? await URLSession.shared.data(from: URL(string: "http://....")!),
let response = try? JSONDecoder().decode(Response.self, from: data) else {
return
}
self.name = response.name
}
}
Does it also run on main thread
没有。这就是 await
的全部意义所在。在那一刻,系统可以在您不知情或不关心的情况下将上下文切换到后台线程。此外,在 await
你的代码 暂停而不阻塞 — 这意味着当你等待下载时,主线程可以自由地做其他工作,用户可以与您的应用程序等。别担心,开心。
问题不在于您 await
的 URLSession
代码。 运行 在由 URLSession
管理的单独线程上。每当您看到 await
,这意味着当前执行在异步任务 运行 时被挂起,并且当前 actor 可以空闲 运行 其他代码。一切顺利。
唯一潜在的问题是 运行 同步在主要角色上的代码(即,除了我们 await
之外的所有内容)。在这种情况下,唯一相关的部分是代码 在 await
之后 ,在所谓的“延续”中。
在这种情况下,延续包括 JSON 的 decode
和 属性 的更新。这是适度的,你一般都很好 运行宁对主要演员。
但是如果续集包含任何更实质性的东西(例如解码许多兆字节的 JSON 或解码图像等),那么您可能希望将其从主要演员身上移开。但在这种情况下,你很好。
有关详细信息,请参阅 WWDC 2021 视频 Swift concurrency: Behind the scenes。
我有一个 ViewModel
与 @MainActor
隔离,我假设这个 ViewModel
class 的每个部分都应该 运行 在主要演员身上(主线程),对吧?
那么问题来了,URLSession.shared.data
的异步调用呢?
它也在 main thread
上 运行 吗?这不是一个糟糕的做法吗?
@MainActor
class ViewModel {
@Published var name: String = ""
func fetchName() async {
guard let (data, _) = try? await URLSession.shared.data(from: URL(string: "http://....")!),
let response = try? JSONDecoder().decode(Response.self, from: data) else {
return
}
self.name = response.name
}
}
Does it also run on main thread
没有。这就是 await
的全部意义所在。在那一刻,系统可以在您不知情或不关心的情况下将上下文切换到后台线程。此外,在 await
你的代码 暂停而不阻塞 — 这意味着当你等待下载时,主线程可以自由地做其他工作,用户可以与您的应用程序等。别担心,开心。
问题不在于您 await
的 URLSession
代码。 运行 在由 URLSession
管理的单独线程上。每当您看到 await
,这意味着当前执行在异步任务 运行 时被挂起,并且当前 actor 可以空闲 运行 其他代码。一切顺利。
唯一潜在的问题是 运行 同步在主要角色上的代码(即,除了我们 await
之外的所有内容)。在这种情况下,唯一相关的部分是代码 在 await
之后 ,在所谓的“延续”中。
在这种情况下,延续包括 JSON 的 decode
和 属性 的更新。这是适度的,你一般都很好 运行宁对主要演员。
但是如果续集包含任何更实质性的东西(例如解码许多兆字节的 JSON 或解码图像等),那么您可能希望将其从主要演员身上移开。但在这种情况下,你很好。
有关详细信息,请参阅 WWDC 2021 视频 Swift concurrency: Behind the scenes。