前言

在前几篇文章中,咱们介绍了 SwiftData 的简单运用和增删改查操作,以及数据的排序过滤和 Container、context 的概念介绍。

本篇文章首要来解说一下 SwiftData 中的 relationship。

主动揣度

SwiftData 的 relationship 是能够经过你界说的模型结构体主动揣度出来的。也能够经过 @Relationship 宏来显式声明。

一般来说,只有当你不想运用默许配置的时分,才需求显式声明。通常情况下,你是用不到 @Relationship 的。

比方下面的这个比如:

@Model
class School {
    var name: String
    var students: [Student]
    init(name: String, students: [Student]) {
        self.name = name
        self.students = students
    }
}
@Model
class Student {
    var name: String
    var school: School
    init(name: String, school: School) {
        self.name = name
        self.school = school
    }
}

咱们界说了一个 School 和一个 Student的类,而且,在 Student 中运用了 School 声明特点;在 School 中运用 Student 声明一个数组。从上述代码中,SwiftData 能够揣度出:

  • 每个校园能够有许多学生
  • 每个学生只归于一所校园

可是,这两者并不是耦合在一起的,它们是分开的。假如咱们创建了一个学生并设置了它的 school特点,SwiftData 不理解如何将该学生添加到该校园的 students 数组中,它不会主动揣度出这种关系是双向的。

假如,咱们将 Student 改成下面的代码:

@Model
class Student {
    var name: String
    var school: School?
    init(name: String, school: School?) {
        self.name = name
        self.school = school
    }
}

唯一的改变是咱们将 school 声明为了可选类型,这意味着它的值可能为空。做出这一改动是根据安全的考虑:

  • 假如学生和校园之间存在关系,那么设置学生的 school 特点应该将其添加到校园的学生列表中或将其从校园的学生列表中删去
  • 同样,从校园的学生列表中添加或许删去学生,也应该同步修改学生的 school 特点
  • 那么,假如你将一名学生从一所校园中删去,而不将其添加到另一所校园,会产生什么情况呢?

当咱们将 school 特点声明为非可选值的时分,即意味着上述情况是不可能产生的,学生有必要归归于一所校园。假如学生的 school 特点没有被赋值,SwiftData 会触发 crash,由于咱们将其置于无效状况。

另一方面,一旦咱们将 school 特点设置为可选特点,这个危险就消失了:从 students 数组中删去一个学生只会将他们的 school 特点设置为 nil ,所以就没有了崩溃危险。

这里的规矩很简单:假如能够安全地揣度关系,SwiftData 就会去主动揣度。

显式声明

许多时分,这还不行,咱们能够在两个模型之一上运用 @Relationship宏创建显式关系,它显式地阐明连接。例如,咱们能够改变Student类,让它的school特点看起来像这样:

@Relationship(inverse: School.students) var school: School

这能够是可选的,也能够是非可选的——这里没有安全约束,由于你现已准确地告诉 SwiftData 你想要什么。

或许,咱们能够更改 School 类,使其学生特点如下所示:

@Relationship(inverse: Student.school) var students: [Student]