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

Realm删除SwiftUI列表行报错:对象已删除或失效,如何修复?

解决Realm删除后SwiftUI List报错“Object has been deleted or invalidated”的问题

嘿,我之前也踩过这个Realm+SwiftUI的坑,咱们来聊聊问题根源和解决办法:

问题出在哪?

你现在用了@Published var aquaris: [Aquaris]这个普通数组来存储Realm对象,虽然设置了NotificationToken监听变更,但有两个关键问题:

  1. 当你删除Realm对象后,原来数组里的那个对象会变成无效状态(已经被Realm标记为删除),但SwiftUI的ForEach还在尝试引用它(因为你用了id: \.self,而这个对象本身已经失效),所以触发了RLMException。
  2. 手动把Realm的Results转成普通数组的操作,可能和Realm的自动更新机制不同步,导致视图刷新不及时,残留了无效对象的引用。

怎么解决?

核心思路是直接使用Realm的Results集合,而不是转成普通数组,因为Results是Realm提供的自动更新、懒加载的集合,能完美配合SwiftUI的响应式系统。下面是修改后的完整代码:

1. 修正DadesRealm类

把存储数据的类型改成Results<Aquaris>,并调整监听逻辑:

import SwiftUI
import RealmSwift

final class DadesRealm: ObservableObject {
    @Published var aquaris: Results<Aquaris>
    private var cargaToken: NotificationToken?
    
    init() {
        let realm = try! Realm()
        aquaris = realm.objects(Aquaris.self)
        recargarDatos()
    }
    
    private func recargarDatos() {
        // 监听Results的变更,一旦有变化就通知SwiftUI刷新视图
        cargaToken = aquaris.observe { [weak self] _ in
            guard let self = self else { return }
            self.objectWillChange.send()
        }
    }
    
    deinit {
        cargaToken?.invalidate()
    }
}

2. 修正List和删除逻辑

把ForEach的id改成Realm对象的主键(你已经设置了id作为主键),同时优化删除的错误处理:

List{
    ForEach(datosRealm.aquaris, id: \.id) { item in
        Text(item.nombre)
    }.onDelete { (indexSet) in
        guard let index = indexSet.first else { return }
        let aqua = datosRealm.aquaris[index]
        let realm = try! Realm()
        do {
            try realm.write{
                realm.delete(aqua)
            }
        } catch {
            print("删除操作失败:\(error.localizedDescription)")
        }
    }
}

为什么这样改能解决问题?

  • Results自动更新:Realm的Results会在数据发生变更(比如删除、新增、修改)时自动同步,不需要手动转数组,从根源避免了无效对象留在数组里的问题。
  • 用主键作为id:id: \.id使用了对象的唯一主键,即使对象被删除,主键值依然有效,SwiftUI能正确识别列表项的增删变化,不会尝试访问已失效的对象实例。
  • 可靠的视图刷新:通过objectWillChange.send()主动通知SwiftUI视图刷新,确保视图和Realm数据状态完全同步。

这样修改后,你删除列表项时,Realm会立即移除对象,Results自动更新,SwiftUI也会同步刷新列表,不会再出现那个讨厌的RLMException啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:09:52