SwiftUI中List视图的.onDelete造成应用程序崩溃

6
我有一个使用SwiftUI构建的相当简单的应用程序,基本上是主细节类型。 数据存储在Core Data中。 添加和更新记录没有问题,但在从列表视图中删除项目时,应用程序总会崩溃。 我使用.onDelete修饰符进行删除。 我没有收到任何错误消息-只是线程中断。 记录确实被删除,因此我猜测列表视图的重新渲染没有接收到更新后的数据。
我可能是在做梦,但我非常确定删除功能在前两个Beta版中有效。 应用程序仅在设备上运行。 它无法在预览或模拟器中工作。
iOS 13.1,Xcode(11392r),Catalina(19A546d)
这是ContentView():
struct ContentView: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(fetchRequest: ToDoItem.getAllToDoItems()) var toDoItems: FetchedResults<ToDoItem>

    @State private var newToDoItem = ""

    var body: some View {
        NavigationView {
            List {
                 Section(header: Text("Records")) {
                    ForEach(self.toDoItems) { toDoItem in
                        NavigationLink(destination: EditToDo(toDoItem: toDoItem)) {
                            ToDoItemView(title: toDoItem.title!,
                                         firstName: toDoItem.firstName!,
                                         lastName: toDoItem.lastName!,
                                         //createdAt: "\(toDoItem.createdAt!)")
                                createdAt: self.localTimeString(date: toDoItem.createdAt!)
                                        )
                        }
                    }
                    .onDelete { indexSet in
                        let deleteItem = self.toDoItems[indexSet.first!]
                        self.managedObjectContext.delete(deleteItem)

                        do {
                            try self.managedObjectContext.save()
                        } catch {
                            print(error)
                        }
                    }
                    .onMove(perform: move)
                }
            }
            .navigationBarTitle("Customers")
            .navigationBarItems(trailing: EditButton())
        }
    }

    func move(from source: IndexSet, to destination: Int) {
        print("this is the move method with no actions")
    }

    func localTimeString(date: Date) -> String {
        let formatter = DateFormatter()
        formatter.timeZone = .current
        formatter.dateFormat = "M-d-yyyy HH:mm:ss"
        let returnString = formatter.string(from: date)
        return returnString
    }//localTimeString

}

还有managedObject:

public class ToDoItem : NSManagedObject, Identifiable {
    @NSManaged public var id: UUID
    @NSManaged public var createdAt: Date?
    @NSManaged public var title: String?
    @NSManaged public var firstName: String?
    @NSManaged public var lastName: String?
}

extension ToDoItem {

    static func getAllToDoItems() -> NSFetchRequest<ToDoItem> {
        let request: NSFetchRequest<ToDoItem> = ToDoItem.fetchRequest() as! NSFetchRequest<ToDoItem>
        let sortDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)
        request.sortDescriptors = [sortDescriptor]
        return request
    }
}

希望能得到您的指导。


快速思考?将您的闭包代码放入一个函数中,并使用onDelete调用它。移动代码后,请全部注释掉并逐行重新引入(在可能的情况下)。看看能否缩小事物范围。 - user7014451
我有一个有问题的列表(从外部SQL数据库驱动),它在.onAppear时间加载。我经常遇到崩溃,内部tableview与数据不同步。在其他地方阅读时,有人建议Xcode beta 6/7中的列表存在时间问题。我添加了一个微小的延迟DispatchQueue.main.asyncAfter(deadline: .now() + 0.01),现在列表完美地工作了。 - KB-YYZ
我将延迟放置在SwiftUI List View的onAppear闭包中。你应该能够直接在onDelete闭包中保存managedContext后执行相同操作 - 当然,这只是一种解决方法,假设这是beta版中List的错误。 - KB-YYZ
或者更可能的是,将您在onDelete中拥有的所有代码放入延迟闭包中。我知道我的情况不同,但当前版本的列表存在时间问题。 - KB-YYZ
明白了。不幸的是,这对我的情况没有用。我很确定删除过程是有效的 - 问题似乎出在下一个屏幕更新上。 - JohnSF
显示剩余2条评论
1个回答

8

这似乎难以置信,但实体中属性名为“id”是此行为的原因。 我将UUID属性的名称更改为“myID”,现在可以正常删除了。 在更改之前,我更新了Xcode到GM seed 2(在重命名之前仍然发生崩溃)。 预览中列表视图仍然不起作用,但在模拟器和设备上现在可以工作。


1
相同的行为在XCode12 / BigSur中仍然存在。在iOS上删除可以正常工作,但在macOS上运行相同的代码会导致崩溃。 - Jason Crocker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接