Realm DB父子对象查询出现无限循环问题咨询
问题解答
1. Schema设计合理性判断
你的Realm双向关联Schema设计是合理的,完全符合Realm的官方规范:
- 子对象
child通过直接引用parent属性关联父对象,这是Realm中一对一关联的标准写法 - 父对象
parent通过linkingObjects反向关联子对象列表,linkingObjects是Realm专门用来实现反向关联的机制,无需手动维护子对象列表,会自动根据子对象的parent属性同步更新
2. 无限循环问题的根源
你遇到的无限循环并非Realm查询本身的问题,而是将Realm对象转化为普通JavaScript对象(比如JSON序列化、手动遍历转对象)时,父对象包含子对象列表、子对象又包含父对象,形成循环引用链,导致递归遍历无法终止。
Realm查询返回的集合(realm.objects()的结果)是实时代理对象,本身不存在内存循环问题,但一旦要将这些对象转成普通JS对象或JSON字符串,就会触发循环引用问题。
3. 解决方法
方法一:手动指定序列化字段,忽略循环属性
转换Realm对象时,只保留需要的字段,主动跳过会引发循环的反向关联属性:
// 序列化父对象:保留子对象基础信息,跳过子对象的parent属性 function serializeParent(parent) { return { id: parent.id, father_name: parent.father_name, children: parent.children.map(child => ({ id: child.id, first_name: child.first_name })) }; } // 序列化子对象:保留父对象基础信息,跳过父对象的children属性 function serializeChild(child) { return { id: child.id, first_name: child.first_name, parent: { id: child.parent.id, father_name: child.parent.father_name } }; } // 使用示例 const parents = realm.objects('parent'); const serializedParents = Array.from(parents).map(serializeParent);
方法二:为Schema自定义toJSON序列化逻辑
在Schema中定义toJSON方法,直接控制对象的序列化行为,避免循环引用:
const ParentSchema = { name: 'parent', properties: { id: 'string', father_name: 'string', children: { type: 'linkingObjects', objectType: 'child', property: 'parent' }, }, primaryKey: 'id', toJSON() { return { id: this.id, father_name: this.father_name, children: this.children.map(child => child.toJSON()) }; } }; const ChildSchema = { name: 'child', properties: { id: 'string', first_name: 'string', parent: { type: 'parent' }, }, primaryKey: 'id', toJSON() { return { id: this.id, first_name: this.first_name, parent: { id: this.parent.id, father_name: this.parent.father_name } }; } };
之后调用JSON.stringify(parent)就不会出现循环引用报错。
方法三:用第三方库处理循环引用
如果不想手动编写序列化逻辑,可以使用circular-json这类专门处理循环引用的库来完成序列化,不过需要额外引入依赖包。
内容的提问来源于stack exchange,提问作者Amaan Khan
相关产品推荐
相关产品推荐

