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
相关产品推荐
相关产品推荐

