我的
SidebarView
中有一个 NavigationSplitView
。 SidebarView
是具有领先标签的用户列表。
当我尝试从该列表中滑动删除用户时,我的
SideBarLabel
视图中会抛出错误:Fatal error: Unexpectedly found nil while unwrapping an Optional value
。
看起来用户被删除后标签仍然存在。如何从 CoreData 中删除包括标签和用户对象的完整行?
我使用这个删除功能,但不知道如何删除用户标签:
我的删除功能在
SidebarView
:
private func deleteSelectedUser(_ user: User){
print(user)
withAnimation {
moc.delete(user)
}
do {
try moc.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
我的
SidebarView
创建列表和滑动功能的代码:
import SwiftUI
import CoreData
struct SidebarView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(sortDescriptors: [SortDescriptor(\.name)])
var users: FetchedResults<User>
@Binding var selection: User.ID?
var body: some View {
List(selection: $selection) {
Text("Anwender")
.font(.headline)
.multilineTextAlignment(.leading)
ForEach(users) { user in
SidebarLabel(user: user)
.swipeActions { Button(role: .destructive, action: {
deleteSelectedUser(user)
//print("swiped item is: \(user.name!)")
}) {
Label("Remove User", systemImage: "trash")
} }
...
我在列表中创建标签和用户:
import SwiftUI
struct SidebarLabel: View {
//@Environment(\.managedObjectContext) var moc
@ObservedObject var user: User
var body: some View {
Label(user.name!, systemImage: "person.circle")
}
}
您遇到此问题的原因是您的
delete
命令在 withAnimation
块内异步发生,这不会阻止该方法的其余部分。因此,当代码点击 try moc.save()
时,该对象可能尚未真正被删除。然后它会从上下文中删除并且不会保存(直到您下次调用save()
) - 因此它可能仍会出现在获取的结果中,但任何访问它的尝试都将失败。
您可以将动画添加到
withAnimation
中,而不是将保存放在 @FetchRequest
块中,以便您的删除方法更清晰:
struct SidebarView: View {
// ...
@FetchRequest(
sortDescriptors: [SortDescriptor(\.name)],
animation: .default
) var users: FetchedResults<User>
// ...etc...
private func deleteSelectedUser(_ user: User){
do {
moc.delete(user)
try moc.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
如果您仍然发现错误,您可以通过检查用户是否已在您的
SidebarLabel
中删除来获得额外的安全性:
struct SidebarLabel: View {
@ObservedObject var user: User
var body: some View {
if !user.isDeleted {
Label(user.name!, systemImage: "person.circle")
}
}
}