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

Swift 6中从仓库加载数据后列表无数据显示的问题求助

Swift 6中从仓库加载数据后列表无数据显示的问题求助

嘿,我瞅了你的代码,很快就找到问题所在啦!你的代码里有几个关键细节没处理对,导致数据更新了但视图根本没收到刷新通知,所以列表才一片空白。

咱们一步步说问题和修复方案:

问题1:Repository无法通知数据变化

你的Repository是个普通类,哪怕data属性更新了,持它的ViewModel和上层View完全感知不到。虽然ViewModel用了@Observable,但它管不了内部普通对象的属性变化呀!

问题2:异步方法调用没等待

你在ViewModel的loadData里调用repository.loadData(),但没加await——哪怕是硬编码的数据,这个异步方法也需要等待它执行完,不然代码会直接跳过,等不到数据赋值完成。

问题3:没必要的嵌套Task

Repository的loadData本身就是async方法,你还在里面嵌套了一个Task,这完全是画蛇添足,反而可能打乱执行时序。


现在给你贴修复后的完整代码,每一处都改到位了:

struct ContentView: View {
    @State private var vm: ViewModel = ViewModel()
    
    var body: some View {
        List(vm.repository.data) { item in
            Text(item)
        }
        .onAppear {
            Task {
                await vm.loadData()
            }
        }
    }
}

@MainActor @Observable final class ViewModel {
    let repository = Repository()
    
    func loadData() async {
        // 必须await仓库的异步方法,确保数据加载完成
        await repository.loadData()
    }
}

@MainActor @Observable final class Repository: Sendable {
    // 标记类为@Observable,属性变化会自动通知视图
    var data: [String] = []
    
    func loadData() async {
        // 真实场景这里可以替换成网络请求等异步操作
        // 加个sleep模拟真实异步延迟
        try? await Task.sleep(for: .seconds(1))
        data = ["item1", "item2"]
    }
}

修复逻辑说明:

  • 给Repository加上@Observable和@MainActor,这样它的data属性一更新,就能自动通知到ViewModel和View,触发列表刷新。
  • 在ViewModel的loadData里加上await,确保等待仓库的数据加载完成。
  • 去掉了嵌套的无用Task,让异步逻辑更清晰。

这样改完之后,你运行代码就能看到列表正常显示item1和item2啦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:53:07