【问题标题】:Unable to initialize @StateObject ViewModel in SwiftUI无法在 SwiftUI 中初始化 @StateObject ViewModel
【发布时间】:2021-12-20 10:54:40
【问题描述】:

我试图在 ViewModel 中注入 managedObjectContext,但由于某种奇怪的原因,它抛出了一个奇怪的错误。

struct ContentView: View {
   
    @Environment(\.managedObjectContext) var viewContext
    @StateObject var addBudgetVM: AddBudgetViewModel
    
    init() {
        // THIS LINE CAUSES ISSUES 
        addBudgetVM = AddBudgetViewModel(context: viewContext)
    }
    
    var body: some View {
       // some code here
    }
    
}

Cannot assign to property: 'addBudgetVM' is a get-only property

这里是 AddBudgetViewModel 的实现

import Foundation
import CoreData

class AddBudgetViewModel: ObservableObject {
    
    @Published var name: String = ""
    var context: NSManagedObjectContext
    
    init(context: NSManagedObjectContext) {
        self.context = context
    }
    
    func save() {
        
    }
    
}

【问题讨论】:

  • @workingdog 但我需要通过 managedObjectContext
  • 您可以在您的视图模型上将上下文设为可选,并将其设置为onAppear
  • 或者将视图模型注入到视图中
  • 我同意@JoakimDanielson。您应该从父视图注入视图模型

标签: ios core-data swiftui


【解决方案1】:

我发现最好的方法是从父视图注入视图模型。这很好地将使用视图模型的视图与视图模型的创建分开。它提高了可测试性,因为它使注入模拟视图模型变得容易。

类似:


struct ParentView: View {
      @Environment(\.managedObjectContext) var viewContext

      var body: some View {
          //...
          AddBudgetView(viewModel: AddBudgetViewModel(context: viewContext))
          //...
      }
}


struct AddBudgetView: View {

      viewModel: AddBudgetViewModel 

      var body: some View {
          // ...
      }
}

class AddBudgetViewModel: ObservableObject {

    private (set) var context: NSManagedObjectContext

    init(context: NSManagedObjectContext) {
    
        self.context = context
    }

   func save() {
    
   }
}

我什至可能在视图模型中都没有 Core Data 代码。我会将所有这些放在主模型中,并将主模型实例传递给视图模型初始化程序,而不是托管对象上下文。然后视图模型可以调用主模型上的方法来创建和保存项目。通过这种方式,您的视图模型与存储实现细节隔离,您可以对存储进行更改,例如替换 Core Data,而无需在所有地方触摸视图模型。

【讨论】:

    猜你喜欢
    • 2021-09-30
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多