如何使用异步数据更新SwiftUI视图?
问题原因及解决方案
你的代码里视图不更新的核心原因有两个:
CurrentUser类没有实现ObservableObject,也未用@Published标记需要监听的属性,SwiftUI无法感知它的属性变化ContentView里的currentUser是普通常量(let),即便内部属性变化,视图也不会重新渲染
修正步骤:
让
CurrentUser成为可观察对象
给CurrentUser添加ObservableObject协议,并将需要监听的属性标记为@Published,让SwiftUI能捕捉到属性变化。在视图中正确监听用户对象
把ContentView里的currentUser从普通常量改成@ObservedObject,或者直接监听UserService的单例对象(因为它是全局共享的)。
修改后的完整代码:
import SwiftUI import Foundation class CurrentUser: ObservableObject { @Published var id = "" @Published var nickname = "" } class UserService { @Published var currentUser = CurrentUser() static var shared = UserService() private init() { } } class ViewModel: ObservableObject { func fetchCurrentUser() async { let currentUser = UserService.shared.currentUser // CurrentUser的属性是@Published,修改会自动触发视图更新 currentUser.id = "007" currentUser.nickname = "James Bond" } } struct ContentView: View { @StateObject private var viewModel = ViewModel() @ObservedObject private var userService = UserService.shared var body: some View { VStack(spacing: 10) { Text("ID: \(userService.currentUser.id)") Text("Nickname: \(userService.currentUser.nickname)") } .task { await viewModel.fetchCurrentUser() } } }
额外说明:
- 如果不想让
UserService直接持有@Published的currentUser,也可以让ViewModel持有一个@Published的CurrentUser实例,然后在视图中绑定viewModel.currentUser。 - 异步函数
fetchCurrentUser里的修改不需要额外的DispatchQueue或MainActor,因为@Published属性的修改会自动在主线程触发视图更新(如果是在后台线程修改,才需要切换到主线程,你的代码是同步修改,无需额外操作)。
内容的提问来源于stack exchange,提问作者CeilingTiles
相关产品推荐
相关产品推荐

