Swift Realm临时存储方案咨询:修改对象时暂存不影响原数据
针对Realm对象编辑暂存的可行方案
核心问题拆解
你需要的是编辑过程中暂存修改(后台切换不丢失)、不影响原对象、点击保存才合并到正式存储,同时避免代码重复、标记冲突、多配置数据交叉可见的问题。以下是针对性的可行方案:
方案1:独立临时Realm存储草稿(推荐)
这是最直接解决你第三个方案问题的方式——之前你创建不同配置但数据可见,大概率是因为没指定独立的文件路径/名称,导致两个配置指向了同一个Realm文件。
实现步骤:
- 创建完全隔离的草稿Realm配置:
// Kotlin示例,其他平台语法类似 val draftConfig = RealmConfiguration.Builder() .name("draft_db.realm") // 与正式库(如default.realm)完全区分 .schemaVersion(1) .build() - 编辑初始化:从正式Realm中读取原对象,通过
copyFromRealm()得到非托管对象,修改后写入草稿Realm(无需创建新的模型类,直接复用原RealmObject) - 后台自动保存:只要在编辑页生命周期销毁前(如
onPause),将当前修改的对象写入草稿Realm,后台切换时数据不会丢失 - 保存/取消操作:
- 保存:打开正式Realm,将草稿对象的字段同步到原对象,提交事务后删除草稿Realm中的对应数据
- 取消:直接删除草稿Realm中的对应数据
- 创建完全隔离的草稿Realm配置:
解决痛点:
- 完全隔离正式与草稿数据,不会出现交叉可见的问题
- 复用原模型类,避免代码重复(无需创建Base/EditedObject)
- 后台切换时数据持久化,不会丢失
方案2:通用草稿模型(复用正式模型字段)
如果不想维护两个Realm实例,可以在正式Realm中创建一个通用的草稿模型,专门存储修改的字段,与原对象通过ID关联:
定义通用草稿模型:
class Draft : RealmObject { @PrimaryKey var draftId: String = "" // 格式:[对象类型]_[原对象ID],如"User_1001" var objectType: String = "" // 标记原对象的类型,用于后续匹配 var modifiedFields: RealmMap<String, Any?> = RealmMap() // 存储修改的字段名与值 var createTime: Long = System.currentTimeMillis() }实现逻辑:
- 编辑时,将修改的字段逐一存入
modifiedFields,写入正式Realm - 后台切换时自动保存该Draft对象
- 保存时,根据
objectType和原对象ID找到正式对象,遍历modifiedFields更新对应字段,完成后删除Draft - 取消编辑直接删除Draft
- 编辑时,将修改的字段逐一存入
解决痛点:
- 无需维护多个Realm实例
- 通用模型适配所有需要编辑的对象,避免重复定义草稿类
方案3:事务暂存+生命周期管理(短期暂存)
如果只是短期暂存(如编辑过程中后台切换但进程未被杀),可以结合Realm的未提交事务+平台生命周期组件(如Android ViewModel):
实现逻辑:
- 编辑时开启一个Realm写事务,修改对象但不提交
- 将Realm实例和修改后的对象绑定到ViewModel(或类似生命周期容器),避免页面销毁时被回收
- 后台切换时保持事务状态,回到前台继续编辑
- 保存时提交事务,取消时回滚事务
注意:如果进程被杀,未提交的事务会丢失,因此该方案需配合方案1或2做持久化兜底。
你的问题解答
是否支持同一存储的多版本?
Realm支持的是Schema版本升级(用于模型结构变更时的迁移),并非数据隔离的多版本。如果你需要的是正式数据与草稿数据隔离,必须使用独立文件路径的Realm实例,而非同一存储的多版本。能否将RealmObject分别存储在常规Realm和临时Realm中?
可以!只要两个Realm配置指定了不同的文件路径/名称,它们就是完全独立的存储,对象不会在彼此的实例中可见。你之前出现数据都可见的问题,是因为两个配置指向了同一个Realm文件。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

