如何在 SwiftUI MVVM ViewModel 中传递/获取核心数据上下文?

Lor*_*lor 4 core-data mvvm swift swiftui

语境

为了对 Core Data 对象进行性能操作,managedObjectContext需要托管对象上下文。在SceneDelegate选中“使用核心数据”选项的情况下生成项目时,上下文通过内部的环境变量传递到 View 中(见下文)。一个相关的问题是为什么必须通过环境变量传递核心数据上下文对象?

let contentView = MainView().environment(\.managedObjectContext, context)
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将 传递context到视图模型时,它会抱怨以下内容

不能在属性初始值设定项中使用实例成员“上下文”;属性初始值设定项在 'self' 可用之前运行

struct MainView: View {
    @Environment(\.managedObjectContext) var context
    
    // Computed property cannot be used because of the property wrapper
    @ObservedObject var viewModel = ViewModel(context: context)
}

class ViewModel: ObservableObject {
    var context: NSManagedObjectContext
}
Run Code Online (Sandbox Code Playgroud)

添加一个init()来初始化视图内的视图模型会导致不同的错误,从而导致构建失败。

未能产生表达诊断;请提交错误报告

    init() {
        self.viewModel = ViewModel(context: context)
    }
Run Code Online (Sandbox Code Playgroud)

那么如何在视图模型中使用/获取/传递上下文呢?在视图模型中获取上下文的更好方法是什么?

Asp*_*eri 7

这是你的场景

let contentView = MainView(context: context)          // << inject
        .environment(\.managedObjectContext, context)

struct MainView: View {
    @Environment(\.managedObjectContext) var context

    @ObservedObject private var viewModel: ViewModel // << declare

    init(context: NSManagedObjectContext) {
        self.viewModel = ViewModel(context: context)   // initialize
    }
}

Run Code Online (Sandbox Code Playgroud)

  • 每次呈现视图时都会调用 init 函数。可能这个视图“MainVeiw”只出现一次,但通常这会导致 ViewModel 被初始化多次。 (3认同)