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

SwiftUI+MVVM架构下CoreData新增条目仅重启App才显示问题

问题根源

你遇到的新增数据不实时刷新的核心原因是AddTaskView中创建了独立的TaskListViewModel实例,和TaskListView持有的ViewModel不是同一个对象:

  • 删除操作是在TaskListView所属的ViewModel中执行,删除后直接调用了当前实例的fetchTasks方法刷新了taskList发布属性,所以列表实时更新
  • 新增操作完成后,你没有触发TaskListView所属ViewModel的fetchTasks方法,列表的数据源没有更新,只有重启App时ViewModel重新初始化调用fetchTasks才会加载到新增数据

你不需要将fetchTasks方法迁移到CoreDataHandler中,迁移方法也无法解决当前实例不统一的问题。

修复步骤

1. 修改AddTaskView的属性定义

删除AddTaskView中自行创建的TaskListViewModel实例,改为外部传入:

struct AddTaskView: View {
    
    @Environment(\.managedObjectContext) var coreDataHandler
    @Environment(\.presentationMode) var presentationMode
    @StateObject var viewModel = AddTaskViewModel()
    // 删掉下面这行自行创建实例的代码
    // @StateObject var taskListViewModel = TaskListViewModel()
    // 改为外部传入
    let taskListViewModel: TaskListViewModel
    
    // 其余原有代码保持不变

2. 新增完成后触发刷新

在AddTaskView的新增按钮点击逻辑中,新增成功后调用传入的ViewModel的fetchTasks方法:

Button(action: {
    viewModel.addTask(taskTitle: titleTextFieldText, taskDueDate: Date()) 
    // 新增这行刷新列表数据源
    taskListViewModel.fetchTasks()
    //Dismiss View if successful
    self.presentationMode.wrappedValue.dismiss()
}, label: {
    // 原有按钮样式代码保持不变
})

3. 打开弹窗时传入当前ViewModel

修改TaskListView中打开AddTaskView的代码,将自身持有的ViewModel传入:

.sheet(isPresented: $showAddTaskView, content: {
    AddTaskView(taskListViewModel: viewModel)
})

优化建议(可选)

你可以使用SwiftUI原生的@FetchRequest属性包装器,或者CoreData的NSFetchedResultsController来自动监听CoreData的数据变化,不需要手动调用fetchTasks刷新数据,避免遗漏刷新时机的问题。

内容的提问来源于stack exchange,提问作者nix.codes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:27:05