You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI @Published属性变更后视图未自动更新问题

问题核心

两个逻辑错误导致视图始终无法响应数据变化:

  • 你在下拉刷新、onAppear的回调里直接初始化了全新的DownloadController()实例,和视图通过@StateObject持有的vm对象完全无关。这些临时生成的控制器实例发起网络请求、给自身@Published属性赋值的操作,根本不会被视图监听到。这些临时实例在代码块执行结束后就会被系统回收,不会影响vm中的任何状态。
  • 控制器的方法逻辑存在时序偏差:
    • finished()方法在网络请求刚发起时就被同步调用,完全没有等待请求结果返回,下拉刷新的加载状态会提前终止
    • URLSession的回调默认运行在后台队列,直接在回调中给@Published属性赋值、没有切回主线程,即便实例对应,也无法稳定触发SwiftUI的视图更新

修正步骤

  • 所有需要调用控制器方法的位置,统一复用视图已经持有的vm实例,不要手动新建DownloadController。你最初用@StateObject持有控制器的写法是正确的,之前替换成@ObservedObject、@State没有效果,本质是根本没把这些属性和实际发起请求的实例关联起来。
  • 调整控制器的网络请求逻辑,补全异步闭包的逃逸标记,把状态赋值、刷新完成的逻辑切到主线程执行,等请求全部处理完成后再触发刷新结束:
class DownloadController: ObservableObject {
     @Published var project = [Project]()

    func getProjectsByUserTokenCompletion(finished: @escaping () -> Void) {
        let url = URL(string: "\(self.Api_URL)/api/v1/webhook/projects/\(self.Api_token)/\(self.UserToken ?? self.Default)")!
        
        var request  = URLRequest(url: url)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("Bearer \(self.Token ?? "")", forHTTPHeaderField: "Authorization")

        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        URLSession.shared.jsonDecodableTask(with: request, decoder: decoder) { (result: Result<getProjects, Error>) in
            // 所有UI状态更新、回调触发都在主线程执行
            DispatchQueue.main.async {
                switch result {
                    case .success(let project):
                        self.project = project.Projects
                        
                    case .failure(let error):
                        print(error)
                }
                finished()
            }
        }.resume()
    }
}
  • 替换视图内所有手动新建控制器的调用代码:
RefreshableScrollView(onRefresh: { done in
    vm.getProjectsByUserTokenCompletion {
        done()
    }
})

.onAppear {
    vm.getProjectsByUserTokenCompletion { }
}

内容的提问来源于stack exchange,提问作者OminousMusic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 09:54:08