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
宏,即使你按正确顺序插入数据,最终的结果也会非常随机。
如果你需要直接操作数组,确保所有数据都先插入是非常重要的。以我们 Teacher
和 Student
的例子为例,这意味着你需要先创建所有数据,插入它们,然后再操作数组,如下所示:
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)
暂无评论内容