多对多关系

温馨提示:本文最后更新于2025-01-19 09:32:29,某些文章具有时效性,若有错误或已失效,请在下方留言

在SwiftData 中,当关系的双方都使用数组时,就会创建多对多关系。这类关系相当常见,比如:一个老师有多个学生,一个学生可以有多个老师;一个演员参演了多部电影,一部电影也有许多演员参与;一个人可以乘坐多辆车,一辆车也可以载多个人,等等。

重要提示:SwiftData 不会自动推断多对多关系,你必须使用 @Relationship 宏显式定义它们。由于多对多关系容易出错,因此请仔细阅读以下内容。

首先,定义你的模型,并在其中一方使用 @Relationship 来明确指定反向关系。例如,一个老师有多个学生,一个学生可以有多个老师:

@Model class Student {
    var name: String
    var teachers: [Teacher] = [] // 🚧 警告:为你的关系数组提供默认值
    init(name: String, teachers: [Teacher]) {
        self.name = name
        self.teachers = teachers
    }
}

@Model class Teacher {
    var name: String
    @Relationship(inverse: \Student.teachers) var students: [Student]
    init(name: String, students: [Student]) {
        self.name = name
        self.students = students
    }
}

现在创建并链接您的数据,如下所示:

let teacher1 = Teacher(name: "王老师", students: [])
let student1 = Student(name: "小明", teachers: [teacher1])
let student2 = Student(name: "小爱", teachers: [teacher1])

modelContext.insert(student1)
modelContext.insert(student2)

我们不需要手动插入 Teacher 对象—因为它被两个 Student 使用,SwiftData 会自动插入它。

多对多关系有很多容易出错的地方,而且很遗憾,SwiftData 在这里没有任何宽容空间 ——如果你没有正确地遵循步骤,程序可能会出现奇怪的行为,甚至在运行时崩溃。

例如,如果你在插入 Teacher 之前尝试操作他们的 students 属性,会导致程序崩溃。因此,下面的代码是不可行的:

let tchr = Teacher(name: "王老师", students: [])
let student1 = Student(name: "小明", teachers: [tchr])
let student2 = Student(name: "小爱", teachers: [tchr])

tchr.students.append(student1) // 🛑 不要这样做!
tchr.students.append(student2) // 🛑 不要这样做!

modelContext.insert(tchr)

modelContext.insert(student1)
modelContext.insert(student2)

如果你试图按照错误的顺序插入数据,也会遇到崩溃,并出现消息”illegal attempt to establish a relationship”,例如如下代码:

let tchr = Teacher(name: "王老师", students: [])

modelContext.insert(tchr)

let student1 = Student(name: "小明", teachers: [tchr])
let student2 = Student(name: "小爱", teachers: [tchr])

modelContext.insert(student1)
modelContext.insert(student2)

有趣的是,如果你不小心遗漏了 @Relationship 宏,即使你按正确顺序插入数据,最终的结果也会非常随机。

如果你需要直接操作数组,确保所有数据都先插入是非常重要的。以我们 TeacherStudent 的例子为例,这意味着你需要先创建所有数据,插入它们,然后再操作数组,如下所示:

let tchr = Teacher(name: "王老师", students: [])
let student1 = Student(name: "小明", teachers: [tchr])
let student2 = Student(name: "小爱", teachers: [tchr])

modelContext.insert(tchr)
modelContext.insert(student1)
modelContext.insert(student2)

tchr.students.append(student1)
tchr.students.append(student2)

或者我们可以将 Teacher 添加到 Student 中:

student1.teachers.append(tchr)
student2.teachers.append(tchr)
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容