SwiftUI配置Atlas Device Sync关联时触发RLMException错误求助
Realm关联对象写入错误排查与修复
错误:因未捕获的异常'RLMException'终止应用,原因:'无法在写入事务外修改托管RLMArray。'
我按照官方文档实现写入操作原本正常,但添加对象关联后触发上述错误。相关代码如下:
模型定义
class Dog: Object, ObjectKeyIdentifiable { @Persisted(primaryKey: true) var _id: ObjectId @Persisted var name = "" @Persisted var owner: Person? // 我认为这是错误原因 convenience init(name: String = "", owner: Person) { self.init() self.owner = owner } } class Person: Object, ObjectKeyIdentifiable { @Persisted(primaryKey: true) var _id: ObjectId @Persisted var name = "" @Persisted var dogs: List<Dog> convenience init(name: String) { self.init() self.name = name } }
视图代码
struct AddDogToPersonView: View { @ObservedRealmObject var person: Person @Environment(\.dismiss) var dismiss var body: some View { Form { Section { Button(action: { $person.dogs.append(Dog(name: "Benny", owner: person)) dismiss.callAsFunction() }) { Text("Save") } Button(action: { dismiss.callAsFunction() }) { Text("Cancel") } } } } }
我怀疑这与Dog引用其Owner的逻辑有关,具体代码行如下:
$person.dogs.append(Dog(name: "Benny", owner: person))
问题原因
问题出在初始化Dog时直接给owner赋值了已托管到Realm的person对象——这个赋值操作并没有在写入事务内执行。虽然$person.dogs.append()会触发Realm的自动事务,但创建Dog并设置owner的步骤是在事务外完成的,违反了Realm必须在事务内修改托管对象的规则。
修复方案
方案1:利用绑定在自动事务内设置关联
通过$person.dogs.append()的返回值获取新Dog的绑定,在自动事务内完成owner赋值:
Button(action: { let dogBinding = $person.dogs.append(Dog(name: "Benny")) dogBinding.owner.wrappedValue = person dismiss() }) { Text("Save") }
同时建议修改Dog的便利初始化方法,将owner设为可选参数:
convenience init(name: String = "", owner: Person? = nil) { self.init() self.name = name self.owner = owner }
方案2:手动开启写入事务
显式开启Realm写入事务,在事务内完成所有操作:
Button(action: { guard let realm = person.realm else { return } try! realm.write { let dog = Dog(name: "Benny", owner: person) person.dogs.append(dog) } dismiss() }) { Text("Save") }
内容的提问来源于stack exchange,提问作者tintin
相关产品推荐
相关产品推荐

