swift - 为什么不能将此 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
只是一个“临时”属性——为什么你不能为另一个改变一个?我的猜测是它与对象如何传递到环境中有关,但我不确定。
非常感谢任何见解!
- 编辑:
核心数据用于@FetchRequest
in 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)
}
...