我试图持久化ObjectB的列表是ObjectA,其中将ObjectA添加到列表失败并使整个写事务失败。代码如下,
public final class User: Object {
@Persisted(primaryKey: true) public var userObjectId: ObjectId
.......
@Persisted public var assignments: List<Assignment>
.......
}
public final class Assignment: Object {
@Persisted(primaryKey: true) public var assignmentObjectId: ObjectId
@Persisted public var name: String?
}
使用上述模型,我尝试执行以下操作来创建一个分配,并将创建的分配添加到用户的分配列表中,
func createAssignentForUser(_ user: User) {
do {
let realm = Realm()
try realm.write {
let assignment = Assignment(name: "ass_name")
realm.add(assignment)
user.assignments.append(assignment) //something feels wrong here.
}
} catch {
// handle error
}
}
如果我放置一个调试指针并查询user.assignments。当执行相应的行时,我可以看到计数为1。但是,当我打开Database查看插入的对象时,我既没有看到为Assignment实体创建的任何条目,也没有看到任何添加到用户分配列表中的分配。都是零。上面的代码也不会抛出任何错误。
现在,如果我从上面的代码中删除user.assignments.append(assignment)
行,那么它确实在Assignment实体中创建了一个条目。
有了这行,它似乎没有创建赋值本身,也就是说,realm.add(assignment)
行本身似乎不起作用。
那么上面的代码有什么问题呢?这难道不是将创建的对象添加到列表的正确方法吗?
有许多事情需要纠正,但总的来说,代码将通过一两个小的调整和一些支持信息:
首先,避免Realm和Swift的冲突;List
也是一个SwiftUI对象,这可能会导致编译器混淆。更改
List
@Persisted public var assignments: List<Assignment>
@Persisted public var assignments: RealmSwift.List<Assignment> //added RealmSwift
第二,公共变量只能是var。
public var userObjectId: ObjectId
接下来,这应该不能工作甚至不能编译(它会为我抛出编译错误在call (have 'name:', expected 'value:')中不正确的参数标签
let assignment = Assignment(name: "ass_name")
…因为这就是构造Struct的方法。在Realm中,我们使用类,你需要在你的Realm对象中方便地初始化
public final class Assignment: Object {
@Persisted(primaryKey: true) public var assignmentObjectId: ObjectId
@Persisted public var name: String?
convenience init(name: String) {
self.init()
self.name = name
}
}
最后,你在哪里注意到这个
//something feels wrong here
其实没什么错——只是多余。
realm.add(assignment)
保留赋值对象;但是Realm非常聪明——如果一个对象不存在但又需要存在,它也会在这里持久化assignment
对象
user.assignments.append(assignment)
并将assignment
对象添加到赋值列表中。