我是 Realm 新手,尝试将一个对象链接到另一个对象,如下所示:
func createChild() {
let child = ChildModel()
child.childStr = "ChildHehe"
if let realm = realm {
let data = realm.objects(DataModel.self).filter("title == %@", "Hehe").first
// data confirmed NOT nill
do {
try realm.write {
if let data = data {
data.child.append(child) //No error at all
//data.title = "changedTitle" (Instead if I do this, it works! It only doesn't work when adding child)
}
}
} catch {
print("Error Save Child!")
}
getData()
}
}
func getData() {
if let realm = realm {
let results = realm.objects(DataModel.self).filter("title == %@", "Hehe").first
if let data = results {
print("ID: \(data.id) | Title: \(data.title)")
print("Number of children: \(data.child.count)") // Always count 0 child!
for (index, child) in data.child.enumerated() {
print("Child \(index + 1): \(child.childStr)")
}
}
}
}
我很困惑,即使在 createChild() 函数中添加新子项时没有错误,它总是给出 0 个子项。 我怀疑我的对象模型有问题。这是模型:
class DataModel: Object {
@Persisted(primaryKey: true) var id: UUID
@Persisted var title: String = ""
var child: List<ChildModel> = List<ChildModel>()
//I've tried @Persisted var child: List<ChildModel>, but instead the fetch data is error
}
为什么 child 总是 0,就像没有保存(但写入时没有错误),我怀疑新的 @Persisted 属性的模型有问题。
存在一些编码问题,因此让我们修复它们并提供模板。
从领域对象模型开始,为未来的可扩展性进行编码是一个好主意,因此更改主键。不是必需的,但可能是个好主意。
然后,列表...它必须在 @Persisted 前面,以便 Realm 知道要持久化它,然后还使用
RealmSwift.List
而不是仅仅 List
以避免与 SwiftUI 的命名冲突(即使您不使用 SwiftUI,阅读起来更清晰)
class DataModel: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var title = "" //Realm will infer this is a String type
@Persisted var childList = RealmSwift.List<ChildModel>()
}
我还将
child
属性重命名为 childList
以更好地表示该属性包含的内容。不是错误,但更容易阅读。
然后,编写初始 DataModel 的代码,创建一个 ChildModel,并将其添加到该模型
childList
属性中,以用作完成任务的模板。为了简洁起见,我删除了错误捕获代码。
let realm = try! Realm()
let m = DataModel()
m.title = "Hehe"
try! realm.write {
realm.add(m)
}
let child = ChildModel()
child.childStr = "ChildHehe"
let myData = realm.objects(DataModel.self).where ({ $0.title == "Hehe"}).first!
try! realm.write {
myData.childList.append(child)
}
请注意,我还使用
.where
的类型安全语法而不是 .filter
- 两者都有效,但我会尽可能练习安全语法。
然后简短的代码输出数据对象标题,然后输出它们的 childList 对象的 childStr 属性
let results = realm.objects(DataModel.self).where { $0.title == "Hehe"}
for myData in results {
print("myData title: \(myData.title)")
for child in myData.childList {
print(" childStr: \(child.childStr)")
}
}