Realm Swift中向User的Assignments列表添加对象失败排查
Realm Swift关联关系持久化失败问题排查与解决
问题根源
你的代码出现静默失败的核心原因是:传入的user对象可能不属于当前Realm实例的托管对象。
当你尝试修改一个未被当前Realm管理的对象(比如离线对象、其他线程的Realm对象)的List属性时,Realm的写入事务会无法追踪到该变更,最终导致整个事务的修改都不会被持久化,且不会抛出明确错误——这就是你看到调试时count为1,但数据库中无数据的原因。
另外,原代码中手动调用realm.add(assignment)属于冗余操作,因为将新的Assignment添加到托管User的List时,Realm会自动持久化这个Assignment对象。
正确实现方式
要确保操作的是当前Realm托管的User对象,再执行关联添加操作,以下是两种可靠的实现方案:
方案1:通过主键获取当前Realm的User实例(推荐)
直接通过主键从当前Realm中获取托管的User对象,避免传入外部可能未托管的对象:
func createAssignmentForUser(withUserId userId: ObjectId) { do { let realm = try Realm() // 从当前Realm中获取托管的User对象 guard let managedUser = realm.object(ofType: User.self, forPrimaryKey: userId) else { print("未找到对应ID的用户") return } try realm.write { let assignment = Assignment() assignment.name = "ass_name" // 添加到托管User的List,Realm会自动持久化Assignment managedUser.assignments.append(assignment) } } catch { print("写入事务失败:\(error.localizedDescription)") } }
方案2:处理传入的User对象,确保其为当前Realm托管对象
如果必须传入User对象,先校验并转换为当前Realm的托管实例:
func createAssignmentForUser(_ user: User) { do { let realm = try Realm() var managedUser: User // 校验传入的User是否属于当前Realm if user.realm == nil { // 传入的是离线对象,先添加到当前Realm try realm.write { realm.add(user) } managedUser = user } else if user.realm !== realm { // 传入的是其他Realm的对象,通过主键获取当前Realm的实例 guard let existingUser = realm.object(ofType: User.self, forPrimaryKey: user.userObjectId) else { print("当前Realm中不存在该用户") return } managedUser = existingUser } else { // 已经是当前Realm的托管对象,直接使用 managedUser = user } try realm.write { let assignment = Assignment() assignment.name = "ass_name" managedUser.assignments.append(assignment) } } catch { print("写入事务失败:\(error.localizedDescription)") } }
关键注意事项
- 只操作当前Realm的托管对象:Realm仅会追踪托管对象的变更,离线对象或跨Realm对象的修改不会被持久化。
- 无需手动add关联对象:将新的Object实例添加到托管对象的
List属性时,Realm会自动完成该对象的持久化,无需额外调用realm.add()。 - 不要忽略错误:务必在catch块中打印或记录错误信息,这是排查事务失败原因的关键。
内容的提问来源于stack exchange,提问作者XiOS
相关产品推荐
相关产品推荐

