前言

在前几篇文章咱们介绍了 SwiftData 的基本运用、增修正查操作以及数据的排序和过滤。这篇文章主要介绍 SwiftData 几个主要的类。

ModelContainer、ModelContext 与 ModelConfiguration

SwiftData 有三个比较重要的类:ModelContainer、ModelContext 与 ModelConfiguration。它们的称号尽管比较相似,但功用却是截然不同。

  • ModelContainer 负责创立和管理用于一切 SwiftData 存储需求的实践数据库文件。
  • ModelContext 负责跟踪内存中已创立、修正和删去的一切目标,以便稍后将它们全部保存到模型容器中。
  • ModelConfiguration 确定数据的存储方法和方位,包含运用哪个 CloudKit 容器(假如有)以及是否应启用保存。此装备供给给你的模型容器以确定其行为方法。

每个运用 SwiftData 的项目都需要至少有一个模型容器,以便操作系统知道在哪里读取和写入数据。该容器通常放置在磁盘中,但也或许存储在内存中,以便在应用程序终止时主动清除。

但并非一切内容都需要立即存储在磁盘上。由于,假如咱们总是在磁盘读写咱们正在运用的每一条数据,那是十分消耗功能的。所以,SwiftData 会更喜爱将数据从存储读取到内存中,然后从那里运用它,这样速度更快。当咱们运用 @Query 或类似方法加载数据时,它会存储在这个模型上下文中以便快速拜访。这样咱们就能够进行多次更改,并一次性将它们收效,这是更加高效的一种做法。

模型上下文供给了一些十分有用的额外功用,包含吊销或重做更改的能力以及启用或禁用主动保存的能力。因而,模型上下文存储一切内存中的目标和更改,而模型容器则长期存储它。

由于一切 SwiftData 的项目都有必要至少有一个模型容器,因而你的主 App 结构中通常会包含这样的代码:

.modelContainer(for: XXModel.self)

这还为咱们创立了一个称为 main context 的模型上下文,并将该上下文放入 SwiftUI 的环境中供咱们运用。这个 main context 始终在 Swift 的 main actor 上运行,因而咱们能够安全地从用户界面运用。

Tips:模型容器能够在程序中自在传递,但模型上下文有必要保留在创立它们的线程上。

咱们能够运用 SwiftUI@Environment 特点包装器从环境中读取此内容:

@Environment(.modelContext) var modelContext

@Query 会主动在 SwiftUI 视图中运用相同的上下文。

如何运用 ModelConfiguration 装备自定义的 ModelContainer

当你运用 modelContainer(for:) 获取默许装备时,就意味着 SwiftData 会决议你数据库的存储方位、启用主动保存、禁用吊销等等。你能够重载 modelContainer() 修饰符来修正一些默许装备。

但假如你想彻底操控,则需要自己创立一个 ModelConfiguration 目标,然后运用它去创立你的容器。

例如,假如你想将数据库放在 documents 目录下,则能够运用如下代码:

@main
struct SwiftDataDemoApp: App {
    var container: ModelContainer
    init() {
        do {
            let storeURL = URL.documentsDirectory.appending(path: "database.sqlite")
            let config = ModelConfiguration(url: storeURL)
            container = try ModelContainer(for: Item.self, configurations: config)
        } catch {
            fatalError("Failed to configure SwiftData container.")
        }
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(container)
    }
}

手动创立装备的一大优势是,假如你有特别敏感的数据,或许你或许已经发送了一些在任何情况下都不应更改的模板数据,它允许咱们彻底禁用保存:

let config = ModelConfiguration(allowsSave: false)

手动创立装备的优势在于,你能够运用多个 ModelConfiguration 目标来装备单个模型容器。比方,你希望将 Item 存储在一个文件中,而将用户数据存储在另一个文件中,或许其中一个应该备份到CloudKit,而另一个不应该等等。