【问题标题】:Swift: Nil Error when using self.moc.save() to save in core dataSwift:使用 self.moc.save() 保存核心数据时出现零错误
【发布时间】:2021-07-24 12:48:40
【问题描述】:

由于我将项目更改为使用“objectWillChange.send()”,因此出现 nil 错误。 因为我需要手动更新视图,因为它不会为自定义轮播视图更新自身(因为核心数据?)。

如果我写“1”并点击下一步按钮(NavigationLink)

控制台日志
页面名称:1
捕获错误:nilError

这里是代码。

添加页面类

class AddPage: ObservableObject {
@Environment(\.presentationMode) var presentation
@Environment(\.managedObjectContext) var moc

    func addPage(item: String) {
    
        if item != "" {
        
            let page = Page(context: self.moc)
            page.name = item
        
            do {
                print("page.name: \(page.name ?? "Unknown")")
                try self.moc.save()
            } catch {
            print("catch: \(error)")
            }
        
            objectWillChange.send()
            presentation.wrappedValue.dismiss()
        }
    }
}

添加页面视图

@ObservedObject var add = AddPage()  

NavigationLink(destination: ContentView()){
Text("Next")
    .background(
        Rectangle()
            .frame(width: 330, height: 60, alignment: .center)
    )
    .onTapGesture {
        add.addPage(item: pageName)
    }
}

SceneDelegate 类

added only

var addpage = AddPage()
let contentView = ContentView()
            .environment(\.managedObjectContext, context)
            .environmentObject(addpage)

谁能帮帮我..?

【问题讨论】:

  • 您在执行 . environment(\.managedObjectContext, context) 之前创建了 AddPage 对象,不确定这是否有效。我不会在 AddPage 中使用@Environment(\.managedObjectContext),而是将上下文作为参数注入 init 方法
  • @JoakimDanielson 感谢您的回复!我无法尝试您的方式,因为我不知道如何将“@Environment(\.managedObjectContext)”注入 init 方法。但我可以将值保存在 page.name 中,这意味着它可以与“@Env”一起使用...”?
  • 我的意思是在这里避免@Environment,你应该注入的是context 对象
  • @JoakimDanielson 再次感谢您的回复!我会尝试的。

标签: swift core-data swiftui environment-variables observable


【解决方案1】:

改变

@Environment(\.managedObjectContext) var moc 

如果不是手动获取 moc 之类的东西(如果您使用的是 Xcode 生成的示例代码),那么您可以设置它

var moc = PersistentController.shared.container.viewContext

@Environment 包装器在 class 中不一致,它们只能在 SwiftUI View 中使用。

如果您没有PersistentController,请从具有 SwiftUI 生命周期和 CoreData 的全新项目中获取代码。小心并保留原始堆栈中的名称,它通常是应用程序名称

注释掉(在确定可行之前不要删除)SceneDelegate

中的堆栈代码

创建一个变量

let context = PersistentController.shared.container.viewContext

所以您可以将context 保留在您的View

【讨论】:

  • 感谢您的帮助!!但是如果我把这个“var moc = PersistentController.shared.container.viewContext”放在 AddPage 类中,我得到一个错误,你能告诉我应该把它放在哪里..?错误消息:“在范围内找不到 'PersistentController'”
  • PersistentController 是一个class,它来自 Xcode 在您使用 CoreData 创建新项目时提供的标准代码。将该行替换为为该行提供context 的行.environment(\.managedObjectContext, context) 您必须直接从堆栈中获取上下文。
  • 啊哈..!我从 SwiftUI Life Cycle App 中找到了这条线!目前,我正在使用 UIKit 生命周期,是否还有一种方法可以将这种方法用于 UIKit 生命周期?如果没有办法,当然我会把生命周期改成SwiftUI!
  • 您必须以某种方式访问​​堆栈或创建PersistenceController。我在答案中添加了一些信息,因为它非常适合这里
  • 感谢您的回复!我会尝试测试你写的两种方式!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 2023-03-23
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多