You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RealmSwift添加删除确认弹窗后触发RLMException索引越界错误求助

问题排查:RealmSwift添加删除确认弹窗后触发索引越界错误

问题描述

在使用RealmSwift的SwiftUI应用中,原本通过List+ForEach+onDelete调用删除函数的逻辑可正常运行,但添加删除确认弹窗后,触发RLMException错误:"Index 1 is out of bounds (must be less than 1)",重启App后数据已被删除。

错误原因

  1. SwiftUI List默认行为导致UI与数据源不同步:触发onDelete时,SwiftUI会自动从List的UI中移除对应行,但此时并未删除Realm数据,仅弹出弹窗。这会导致Realm的Live Results(datasets)仍保持完整,但UI已缺失对应行,后续用保存的索引访问datasets时,索引对应关系错位。
  2. 保存索引而非对象的风险:Realm的Live Results是实时更新的,索引会随数据增删随时变化,弹窗确认时,之前保存的索引可能已失效。
  3. 代码笔误:原showMyHint函数中错误使用未定义的indexSet变量(应为参数indexes),且多余的循环会重复赋值forDeletion。

修复方案

放弃保存删除索引,改为保存要删除的Dataset对象本身(对象主键稳定,不会因数据变化失效),确认后直接删除对象,让Realm的Live Results自动同步UI。

修正后完整代码

ViewModel属性调整

@State private var showHint = false
@State private var datasetToDelete: Dataset? // 保存待删除对象,替代原索引集合

List与弹窗逻辑

List {
    ForEach(datasets) { dataset in
        Text("\(dataset.name)")
    }
    .onDelete(perform: showDeleteConfirmation)
}
.alert(isPresented: $showHint) {
    Alert(
        title: Text("警告"),
        message: Text("确定要删除这条记录吗?"),
        primaryButton: .destructive(Text("删除")) {
            if let dataset = self.datasetToDelete {
                RealmService.shared.deleteDataset(dataset)
                self.datasetToDelete = nil
            }
        },
        secondaryButton: .cancel() {
            self.datasetToDelete = nil
        }
    )
}

func showDeleteConfirmation(at indexes: IndexSet) {
    // 取出待删除的对象(处理单条删除场景)
    guard let index = indexes.first else { return }
    self.datasetToDelete = datasets[index]
    self.showHint = true
}

RealmService删除函数(保持原逻辑不变)

func deleteDataset(_ dataset: Dataset) {
    do {
        if let forDeletion = realm.object(ofType: Dataset.self, forPrimaryKey: dataset.id) {
            try realm.write {
                realm.delete(forDeletion)
            }
        } else {
            print("DATASET not found or already deleted")
        }
    } catch {
        print("Error deleting DATASET: \(error.localizedDescription)")
    }
}

说明

  • 触发onDelete时直接取出对应对象保存,避免索引失效问题。
  • 弹窗确认后直接删除对象,Realm的Live Results会自动更新,List UI同步刷新,无索引错位风险。
  • 上述代码处理单条删除场景,若需支持多选删除,可调整为保存[Dataset]数组并修改弹窗逻辑。

内容的提问来源于stack exchange,提问作者user2836375

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:43:26