Swift 领域异常

Swift Realm exception

在我的 homeViewController 上,我有一个 table带有单元格的视图。
单元格中填充了来自 Realm 数据库的数据。
每个单元格都可以删除。
删除单元格后一切正常
当我转到另一个 viewController,然后再次返回主页时,应用程序崩溃,原因:

"Object has been deleted or invalidated."

有什么想法吗?重新加载数据和类似的东西没有帮助。
我是 Realm 新手。

这是我从 Realm 读取数据到 table

的地方
override func viewWillAppear(_ animated: Bool) {
    //tableView.reloadData()
    let realm = try! Realm()
    let result = realm.objects(CardsetTable.self)
    for r in result {
        self.cardsets.append(r)
    }
    for x in cardsets{
        self.titles.append(x)
    }
    self.tableView.reloadData()
}

这是我删除单元格和领域数据的地方:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let newSet = CardsetTable()
        newSet.cards = self.titles[indexPath.row].cards
        newSet.size = self.titles[indexPath.row].size
        newSet.title = self.titles[indexPath.row].title
        newSet.id = self.titles[indexPath.row].id
        let realm = try! Realm()
        try! realm.write {
            realm.delete(realm.objects(CardsetTable.self).filter("title=%@",titles[indexPath.row].title))
        }
        titles.remove(at: indexPath.row)
    }

    tableView.beginUpdates()
    tableView.deleteRows(at: [indexPath], with: .automatic)
    tableView.reloadData()
    tableView.endUpdates()
}

此处有几处需要改进。 在 viewWillAppear 中,您正在从领域获取结果并在您的 editingStyle: 方法中再次执行相同操作,这是不必要的。

let result = realm.objects(CardsetTable.self)

您正在将结果添加到数组 self.cardsets,这不是必需的。您可以将 result 用作数组并根据索引访问其元素。

您可能在 viewWillAppear 中添加了不必要的领域元素,因为 viewWillAppear 可能会被多次调用,您需要注意在数组中添加领域元素如果您不删除之前添加的元素,则会重复。

即将使用 editingStyle 方法,

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let newSet = CardsetTable()
        newSet.cards = self.titles[indexPath.row].cards
        newSet.size = self.titles[indexPath.row].size
        newSet.title = self.titles[indexPath.row].title
        newSet.id = self.titles[indexPath.row].id
        let realm = try! Realm()
        try! realm.write {
            realm.delete(realm.objects(CardsetTable.self).filter("title=%@",titles[indexPath.row].title))
        }
        titles.remove(at: indexPath.row)
    }

    tableView.beginUpdates()
    tableView.deleteRows(at: [indexPath], with: .automatic)
    tableView.reloadData()
    tableView.endUpdates()
}

我真的不确定为什么你创建了一个新的 Realm 对象 let newSet = CardsetTable() 并且不使用它。

在这一行:

realm.delete(realm.objects(CardsetTable.self).filter("title=%@",titles[indexPath.row].title))

您正在从您的领域数据库中重新获取项目。这也是不必要的。您可以在预取的领域数组 self.cardsets

上调用 filter 方法

错误的可能性有很多种。它说您要删除的对象已被删除或不再有效。

我看到两个可能的原因:

1 - realm.objects(CardsetTable.self) 返回的领域对象之一已被删除

2 - titles[indexPath.row] 正在返回一个领域对象,然后访问 .title 将导致错误,因为 titles[indexPath.row] 已经从 db.

中删除

您始终可以验证对象是否无效

  if (!rlmObj.isInvalidated){
        // delete
   }

正如 dávid-pásztor 所说,您不应该从 beginUpdates 操作内部调用 reloadData。

您的崩溃可能与此处未显示的代码有关。您如何显示 table 个单元格以及如何使用存储在卡组和标题中的领域 objects。这可能是崩溃的原因,因为您的视图控制器正在保留已从领域中删除的领域 objects。

当项目从领域中删除时,您需要更新您的卡组和头衔。

旁注,为什么要将相同的领域 objects 存储在两个不同的数组中?