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

RxSwift+Realm绑定UITableView删除对象崩溃:RLMException求助

解决Realm+RxSwift删除对象时的RLMException崩溃问题

我之前帮朋友排查过一模一样的问题,你遇到的'Object has been deleted or invalidated.'崩溃,核心原因是Realm对象被删除后,绑定到UITableView的Rx序列里还持有这个已失效的对象引用,当UITableView尝试访问这个无效对象的属性时,就触发了Realm的异常。

问题根源拆解

你用RxSwift把Realm的Results<T>查询结果直接绑定到UITableView,虽然Results是Realm的实时更新集合,但Rx默认的绑定逻辑不会自动过滤掉已经被删除/失效的对象。当你删除某个对象后,这个对象会变成isInvalidated == true的状态,但它还留在Rx的序列里,UITableView渲染时去读取它的属性,自然就会抛出异常。

分步骤解决方案

1. 手动过滤失效对象(不依赖第三方库)

在Rx绑定的序列里,添加一个过滤操作,只保留未失效的对象:

// 假设你的Realm模型是TodoItem
realm.objects(TodoItem.self)
    .asObservable()
    // 过滤掉已失效的对象
    .map { $0.filter { !$0.isInvalidated } }
    .bind(to: tableView.rx.items(cellIdentifier: "TodoCell")) { index, item, cell in
        cell.textLabel?.text = item.content
    }
    .disposed(by: disposeBag)

2. 确保删除操作在Realm写事务中执行

删除Realm对象必须在写事务里进行,这是Realm的强制要求,同时也能保证Results集合实时更新:

deleteFirstButton.rx.tap
    .subscribe(onNext: { [weak self] in
        guard let self = self else { return }
        let realm = try! Realm()
        if let firstItem = realm.objects(TodoItem.self).first {
            try! realm.write {
                realm.delete(firstItem)
            }
        }
    })
    .disposed(by: disposeBag)

⚠️ 注意:不要在ViewModel或其他地方持有已删除对象的强引用,否则即使删除了,内存里的无效对象还是会被访问到。

3. 用RxRealm库简化绑定(推荐)

官方维护的RxRealm库已经帮我们处理了对象失效、集合更新的所有细节,用它来绑定Realm查询会更安全:
先在依赖管理工具中添加RxRealm,然后导入库使用:

import RxRealm

// 用RxRealm的rx.observe()方法创建安全的Observable
realm.objects(TodoItem.self)
    .rx.observe()
    .bind(to: tableView.rx.items(cellIdentifier: "TodoCell")) { index, item, cell in
        cell.textLabel?.text = item.content
    }
    .disposed(by: disposeBag)

rx.observe()会自动过滤无效对象,并且优化了Realm集合更新的通知逻辑,删除对象后UITableView会自动正确刷新,完全不会触发崩溃。

验证方法

按照上面的修改后,点击deleteFirst按钮,UITableView会自动移除被删除的行,同时不会再抛出RLMException异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:28:23