【发布时间】:2020-03-26 03:39:07
【问题描述】:
我发现在 SwiftUI 中无法使用核心数据,因为当我将核心数据传递给视图观察对象变量时,导航链接视图将保持对该对象的引用,即使在视图消失后,只要我从应用程序崩溃的上下文中删除对象,没有错误消息。
我已经通过将核心数据对象变量作为可选包装到视图模型中来确认这一点,然后在上下文删除操作之后立即将该对象设置为 nil 并且应用程序工作正常,但这不是解决方案,因为我需要绑定到 swift ui 视图并成为事实来源的核心数据对象。这应该如何工作?看来,我真的无法用 SwiftUI 让任何事情变得复杂。
我尝试将传入的核心数据对象分配给可选的@State,但这不起作用。我不能使用@Binding,因为它是一个获取的对象。而且我不能使用变量,因为 swiftui 控件需要绑定。使用@ObservedObject 才有意义,但这不能是可选的,这意味着当分配给它的对象被删除时,应用程序会崩溃,因为我无法将其设置为 nil。
这里是核心数据对象,默认是可观察对象:
class Entry: NSManagedObject, Identifiable {
@NSManaged public var date: Date
}
这是一个将核心数据条目对象传递给另一个视图的视图。
struct JournalView: View {
@Environment(\.managedObjectContext) private var context
@FetchRequest(
entity: Entry.entity(),
sortDescriptors: [],
predicate: nil,
animation: .default
) var entries: FetchedResults<Entry>
var body: some View {
NavigationView {
List {
ForEach(entries.indices) { index in
NavigationLink(destination: EntryView(entry: self.entries[index])) {
Text("Entry")
}
}.onDelete { indexSet in
for index in indexSet {
self.context.delete(self.entries[index])
}
}
}
}
}
}
现在这里是从传入的核心数据条目对象访问所有属性的视图。有一次,我删除了这个条目,顺便说一下,从任何视图中,它仍然在这里引用并导致应用程序立即崩溃.我相信这也与导航链接在访问之前初始化所有目标视图有关。这是没有意义的,为什么会这样做。这是一个错误,还是有更好的方法来实现这一点?
我什至尝试过删除 onDisappear,但没有成功。即使我从 JournalView 中删除,它仍然会崩溃,因为 NavigationLink 仍在引用该对象。有趣的是,如果删除尚未点击的 NavigationLink,它不会崩溃。
struct EntryView: View {
@Environment(\.managedObjectContext) private var context
@Environment(\.presentationMode) private var presentationMode
@ObservedObject var entry: Entry
var body: some View {
Form {
DatePicker(selection: $entry.date) {
Text("Date")
}
Button(action: {
self.context.delete(self.entry)
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Delete")
}
}
}
}
更新
崩溃使我第一次使用 EntryView 中的条目并读取 Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).. 这是唯一抛出的消息。
我能想到的唯一解决方法是向核心数据对象“isDeleted”添加一个属性并将其设置为 true,而不是尝试从上下文中删除。然后当应用程序退出或启动时,我可以清理并删除所有已删除的条目?不理想,并且希望在这里找出问题所在,因为看起来我没有做任何与 MasterDetailApp 示例不同的事情,这似乎有效。
【问题讨论】:
-
真是麻烦!这个@SybrSyn 有什么更新吗?!