【问题标题】:Swift - Thread 1: EXC_BAD_INSTRUCTION when deleting object from CoredataSwift - 线程 1:从 Coredata 删除对象时的 EXC_BAD_INSTRUCTION
【发布时间】:2021-09-12 09:00:28
【问题描述】:

我正在尝试从 Coredata 中删除一个对象,但有时我会收到错误 Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0),当我删除一个对象时,我的应用程序会崩溃。控制台也会吐出大量信息,但这似乎是最重要的:

[General] *** __boundsFail: index 2 beyond bounds [0 .. 1]

奇怪的是,这只发生在我调用函数从警报中删除对象时。

这是删除对象的函数:

    private func deleteInstances(offsets: IndexSet) {
        if instances.count == 1 {
            showingCantDeleteInstanceAlert = true
            return
        }
        
        for index in offsets {
            let instance = instances[index]
            print(instance)
            viewContext.delete(instance)
        }
        
        do {
            try viewContext.save()
        } catch {
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }

        if selectedInstanceIndex ?? 0 >= instances.count {
            selectedInstanceIndex = instances.count - 1
        }
        
    }

我正在使用 focusValue 从菜单命令中调用该函数:

.focusedValue(\.deleteInstanceAction) {
    deleteInstances(offsets: [selectedInstanceIndex ?? 0])//selectedInstanceIndex is the index of the object that is selected in a navigationView and therefore the object I want to delete
}

这总是可以正常工作,但我希望它显示一个警报,以确保用户确实想要删除实例:

.focusedValue(\.deleteInstanceAction) {
    showingConfirmDeleteInstanceAlert = true

还有警报:

.alert(isPresented: $showingConfirmDeleteInstanceAlert) {
    Alert(
        title: Text("Are you sure you want to delete instance \"\(instances[selectedInstanceIndex ?? 0].wrappedName)\"?"),
        message: Text("This action cannot be undone."),
        primaryButton: .cancel(),
        secondaryButton: .destructive(Text("Delete")) {
            deleteInstances(offsets: [selectedInstanceIndex ?? 0])
        }
    )
}

但是,当从此处运行该函数时,有时会出现该错误。只有当我尝试删除 navigationView 中的最后一个实例时才会发生这种情况。

我不知道可能会发生什么,据我所知应该以任何一种方式运行相同的代码,但在带有警报的版本中它并不总是有效。

任何帮助弄清楚正在发生的事情将不胜感激。 谢谢!

【问题讨论】:

  • 一个叫“instances”的家伙是哪里来的?
  • @ElTomato 我不确定我是否明白你在问什么。 Instance 是 Coredata 中我希望能够删除的实体的名称。
  • 查看第二行及更多内容。

标签: swift macos core-data swiftui swiftui-alert


【解决方案1】:

尝试使用实例的 managedObjectContext,比如:

let context = instance.managedObjectContext
context.delete(instance)

do {
    try context.save()
} catch {
    let nsError = error as NSError
    fatalError("Unresolved error \(nsError),  \(nsError.userInfo)")
}

如果这不起作用,请尝试将您对该函数的调用推送到主线程,这不是最好的,但您使用的是viewContext,所以您必须在“UI 线程”或主线程上线。就像这样:

DispatchQueue.main.async {
    deleteInstances(offsets: [selectedInstanceIndex ?? 0])
}

【讨论】:

  • 您的第二个建议奏效了,谢谢!我是 swift 新手,所以我不熟悉 dispatchQueue 之类的高级概念(至少对我来说是高级的),所以我可能会尝试做一些研究来理解它以及我做错了什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 2011-06-06
  • 1970-01-01
相关资源
最近更新 更多