关系与 FetchDescriptor
建模一对多关系,并使用 FetchDescriptor 查询。
关系与 FetchDescriptor 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
SwiftData 关系
使用 Swift 属性在 @Model 类之间声明关系。SwiftData 会推断关系类型。
@Model
class Author {
var name: String
@Relationship(deleteRule: .cascade) var books: [Book] = []
init(name: String) { self.name = name }
}@Relationship 属性
使用 @Relationship 显式指定删除规则和逆向关系。
@Model
class Book {
var title: String
var author: Author?
init(title: String) { self.title = title }
}删除规则
删除规则控制删除父对象时相关对象的处理方式:.nullify、.cascade、.deny。
// .cascade: deleting Author deletes all Books
// .nullify: deleting Author sets book.author to nil
// .deny: prevents deletion if related objects exist
@Relationship(deleteRule: .cascade) var books: [Book] = []一对多关系
一对多关系在“一”这一侧声明为数组属性。
@Model class Department {
var name: String
@Relationship(deleteRule: .cascade) var employees: [Employee] = []
init(name: String) { self.name = name }
}
@Model class Employee {
var name: String
var department: Department?
init(name: String) { self.name = name }
}多对多关系
在两侧都声明数组,即可建立多对多关系。
@Model class Student {
var name: String
var courses: [Course] = []
init(name: String) { self.name = name }
}
@Model class Course {
var title: String
var students: [Student] = []
init(title: String) { self.title = title }
}FetchDescriptor
FetchDescriptor 在 SwiftData 中取代了 NSFetchRequest。您可以为其配置谓词、排序方式和获取上限。
var descriptor = FetchDescriptor<Book>(
predicate: #Predicate { $0.title.contains("Swift") },
sortBy: [SortDescriptor(\Book.title)]
)
descriptor.fetchLimit = 10
let books = try context.fetch(descriptor)使用 SortDescriptor 排序
将 SortDescriptor 数组传递给 FetchDescriptor,以进行多列排序。
let descriptor = FetchDescriptor<Item>(
sortBy: [
SortDescriptor(\Item.priority, order: .reverse),
SortDescriptor(\Item.name)
]
)无需获取即可计数
使用 context.fetchCount 统计匹配记录的数量,而无需将所有对象加载到内存中。
let descriptor = FetchDescriptor<Book>(
predicate: #Predicate { $0.rating > 4 }
)
let count = try context.fetchCount(descriptor)
print("High-rated books: \(count)")预获取关系
在 FetchDescriptor 上设置 relationshipKeyPathsForPrefetching,以便预先加载相关对象。
var descriptor = FetchDescriptor<Author>()
descriptor.relationshipKeyPathsForPrefetching = [\Author.books]
let authors = try context.fetch(descriptor)带有类似 FetchDescriptor 选项的 @Query
@Query 宏支持与 FetchDescriptor 相同的排序和谓词选项。
@Query(
filter: #Predicate<Book> { $0.author?.name == "Apple" },
sort: \Book.title
)
var books: [Book]批量操作
SwiftData 通过 context.delete(model:where:) 支持批量删除,以高效执行批量操作。
try context.delete(model: Book.self, where: #Predicate { $0.rating < 2 })快速检查
哪个 SwiftData 类型取代了 NSFetchRequest,可用于获取带筛选条件和排序的 @Model 对象?
课程回顾
在 @Model 类上使用 @Relationship(deleteRule:) 声明关系。使用带有 #Predicate 和 SortDescriptor 的 FetchDescriptor 查询数据。使用 fetchCount 进行计数,并使用批量删除批量移除数据。
常见问题解答
「关系与 FetchDescriptor」课时是免费的吗?
是的 — 「关系与 FetchDescriptor」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「关系与 FetchDescriptor」这节课中我会学到什么?
建模一对多关系,并使用 FetchDescriptor 查询。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「关系与 FetchDescriptor」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Core Data 堆栈:设置 NSPersistentContainer
- SwiftData @Model 与 ModelContext
- 关系与 FetchDescriptor
- 轻量级迁移与 CloudKit 同步