【问题标题】:SwiftUI @FetchRequest crashes the app and returns errorSwiftUI @FetchRequest 使应用程序崩溃并返回错误
【发布时间】:2020-06-07 08:43:30
【问题描述】:

我正在尝试使用 Xcode 11 在我的 Mac 应用程序中通过 SwiftUI 使用核心数据。 我在创建项目时检查了“使用核心数据”。 我还创建了实体(称为 VisitedCases)并使用编辑器创建 NSManagedObject 子类文件。我还将 Codegen 设置为 Manual/none。 这是生成的 NSManagedObject 文件中的代码:

VisitedCases+CoreDataProperties.swift

extension VisitedCases {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<VisitedCases> {
        return NSFetchRequest<VisitedCases>(entityName: "VisitedCases")
    }

    @NSManaged public var caseNumber: String

} 

VisitedCases+CoreDataClass.swift

@objc(VisitedCases)
public class VisitedCases: NSManagedObject {

}

我将 ContentView.swift 中的@Environment 变量和@FetchRequest 称为:

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

    @FetchRequest(entity: VisitedCases.entity(),
                  sortDescriptors: []
                  ) var orders: FetchedResults<VisitedCases>
//@State vars and the rest of the code
}

但是,当我运行时,应用程序在启动后立即崩溃,并在输出中显示以下错误:

2020-02-23 18:36:16.889306+0330 ImageSelector[17874:149503] [error] error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'VisitedCases' so +entity is confused.  Have you loaded your NSManagedObjectModel yet ?
CoreData: error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'VisitedCases' so +entity is confused.  Have you loaded your NSManagedObjectModel yet ?
2020-02-23 18:36:16.889389+0330 ImageSelector[17874:149503] [error] error: +[VisitedCases entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
CoreData: error: +[VisitedCases entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
2020-02-23 18:36:16.921131+0330 ImageSelector[17874:149503] executeFetchRequest:error: A fetch request must have an entity.

我还有一个函数可以将字符串保存到存储中,并且似乎工作得很好:

    func addCaseNumber (caseNo: String) {
        guard caseNo != "" else {return}
        let newCaseNumber = VisitedCases(context: self.managedObjectContext)
        newCaseNumber.caseNumber = caseNo
        do {
         try self.managedObjectContext.save()
         print("Case number saved.")
        } catch {
         print(error.localizedDescription)
         }
    }

我的代码有什么问题,我应该怎么做才能修复它?

【问题讨论】:

  • 您似乎没有定义或加载您的核心数据模型。
  • @MarcT。我在创建项目时检查了“使用核心数据”,所以我假设数据对象已被注入到委托等。我还在数据模型中定义了实体并验证了它的名称。我错过了什么?
  • @CranialDev 我已经检查过这个问题。我无法将 Codegen 切换到 Category/Extension,因为它也会因同样的错误而崩溃。我也没有完全得到从“Product.fetchRequest()”到“NSFetchRequest(entityName:“Product”)”部分的变化。应该在哪里以及如何实施这种改变?
  • 该部分内置在包装器中。如果您查看 FetchedResultsController 的 CoreData 文档,您会看到它们是如何组合在一起的。您是否手动创建 CoreData 堆栈?

标签: swift macos swiftui swift5 xcode11


【解决方案1】:

这对我有用,因为我正在为我的 CoreData 实体使用 NSManagedObject 子类(代码生成定义上的手动/无),因为我正在展开一些包装。我必须删除该类并使用编辑器再次生成然后一切都再次工作

【讨论】:

    【解决方案2】:

    尝试像这样在您的ContentView 中分配您的managedObjectContext

    let managedObjectContext: NSManagedObjectContext =  ((UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext)!
    

    如果这有效,则意味着您的 @Environment var 无效。

    要找出中断发生的位置,请从 SceneDelegate 开始

    let contentView = ContentView().environment(\.managedObjectContext, context)
    

    然后查看与Environment的连接在哪里中断

    在你所有的视图中加入这样的东西,看看哪个没有得到Environment 变量。

    @Environment(\.managedObjectContext) var managedObjectContext
         var body: some View {
             print("MOC = ")
             print(managedObjectContext.name ?? "broken")
         return Text("Hello World!")
    }
    

    当你找到中断时,用

    重新建立它
    YourBrokenView().environment(\.managedObjectContext, managedObjectContext)
    

    【讨论】:

    • 成功了!我的@Environment var 有什么问题?
    • 见上图连接可能被破坏了
    • 打印因损坏而返回空
    • 顺便说一句,因为它是一个 mac 应用程序,它没有 SceneDelegate
    【解决方案3】:

    在@enviromentVAr 中,有时需要自己设置环境。

     let managedObjectContext: NSManagedObjectContext =  ((UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext)!
    
     ContentView().environment(\.managedObjectContext, managedObjectContext)
    

    那么managedObjectContext就可以工作了。

     @Environment(\.managedObjectContext) var managedObjectContext
    

    【讨论】:

      猜你喜欢
      • 2020-03-06
      • 2023-01-08
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      • 2020-03-03
      • 2022-01-11
      • 1970-01-01
      相关资源
      最近更新 更多