如何更新带主键的Realm对象(不修改主键仅更新其他字段)
更新Realm带主键对象的非主键字段
要更新Realm中带有主键的UserData对象且不修改主键,其实有两种常用且稳妥的方式,我帮你拆解一下:
方式一:直接用create(_:value:update:)批量更新(推荐用于字典/JSON数据源)
这种方式不需要先查询对象,直接通过主键匹配现有数据,只更新你提供的非主键字段,非常适合从接口返回的JSON或者字典数据更新的场景。
代码示例:
// 准备更新数据:必须包含主键uid(用来匹配目标对象),只填需要更新的非主键字段 let updateDict: [String: Any?] = [ "uid": "your-target-user-uid", // 主键值不能改,用来定位对象 "name": "新的用户名", "bio": "更新后的个人简介", "phone": "138xxxx8888" ] do { let realm = try Realm() try realm.write { // Realm 10.0+版本用.update: .modified,只会更新提供的字段,不覆盖未指定的字段 realm.create(UserData.self, value: updateDict, update: .modified) } print("用户数据更新成功!") } catch { print("更新失败:\(error.localizedDescription)") }
关键说明:
update: .modified是Realm 10.0及以上版本的推荐参数,它只会更新你明确提供的非主键字段,没提到的字段会保持原有值;如果是低于10.0的版本,你可以用update: true,效果类似但.modified更精准。- 如果主键对应的对象不存在,这个方法会自动创建一个新的
UserData对象(如果你不想创建新对象,建议先查询再修改,看方式二)。
方式二:先查询对象再修改(直观易读)
如果需要先读取对象的现有数据再做修改,这种方式更直观:
代码示例:
do { let realm = try Realm() try realm.write { // 通过主键查找目标对象 guard let targetUser = realm.object(ofType: UserData.self, forPrimaryKey: "your-target-user-uid") else { print("找不到对应UID的用户对象,无法更新") return } // 直接修改非主键字段,主键uid不能改! targetUser.name = "修改后的名字" targetUser.bio = "新的个人介绍" targetUser.imageL = UIImage(named: "new-avatar")?.pngData() // 事务提交后自动保存,不需要额外调用save方法 } print("用户数据更新完成") } catch { print("更新出错:\(error.localizedDescription)") }
关键说明:
- 必须在
realm.write闭包内修改对象,Realm的所有写入操作都需要在事务中执行。 - 绝对不要尝试修改主键
uid的值,Realm不允许修改已持久化对象的主键,强行修改会抛出错误。
注意事项
- 对于可选类型字段(比如你的
name、bio都是String?),如果要设置为nil,直接赋值nil或者在字典中传nil即可,Realm会正确处理。 - 如果需要批量更新多个对象,循环调用上述方法即可,或者把多个更新操作放在同一个事务里,提升性能。
内容的提问来源于stack exchange,提问作者Aakash Dave
相关产品推荐
相关产品推荐

