首页 > 解决方案 > 为什么不能将此 ManagedObjectContext 直接传递到 SwiftUI 视图的环境中?

问题描述

当您在 Xcode 12 中启动一个新的 SwiftUI 项目并勾选“使用核心数据”复选框时,您会获得一些模板代码,这些代码将设置一个 SwiftUI 视图,其中托管对象上下文通过环境值注入其中。

像这样:

struct CoreDataTestApp: App {
    let persistenceController = PersistenceController.shared

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

在上面的代码中,persistenceController是一个PersistenceController对象(结构),它可以访问NSManagedObjectContext,这是在 SwiftUI 视图中使用 Core Data 所必需的。以下是相关代码:

struct PersistenceController {
    static let shared = PersistenceController()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "CoreDataTest")
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            ...
        })
    }
}

这一切都有效;它是 Xcode 12 中的默认/模板代码。但是,当您进行以下更改时,它将不再起作用:

struct CoreDataTestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, PersistenceController.shared.container.viewContext)
        }
    }
}

您将收到以下错误:CoreData: error: No NSEntityDescriptions in any model claim the NSManagedObject subclass 'Item' 所以 +entity 被混淆了。你加载你的 NSManagedObjectModel 了吗?

为什么?

我在想,因为PersistenceController.shared它是静态的而不是弱的,所以它被强烈保留,所以内存管理不应该是一个问题。这persistenceController只是一个“临时”属性——为什么你不能为另一个改变一个?我的猜测是它与对象如何传递到环境中有关,但我不确定。

非常感谢任何见解!

- 编辑:

核心数据用于@FetchRequestin ContentView,这里:

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

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        List {
            ForEach(items) { item in
                Text("Item at \(item.timestamp!, formatter: itemFormatter)")
            }
            .onDelete(perform: deleteItems)
        }
...

标签: swiftswiftuiios14xcode12

解决方案


推荐阅读