Realm Swift 如何将对象作为子对象与 @Persisted 属性链接

问题描述 投票:0回答:1

我是 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 属性的模型有问题。

swift realm
1个回答
0
投票

存在一些编码问题,因此让我们修复它们并提供模板。

从领域对象模型开始,为未来的可扩展性进行编码是一个好主意,因此更改主键。不是必需的,但可能是个好主意。

然后,列表...它必须在 @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)")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.