SwiftData 学习笔记:Container 与 context 详解

前言

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

ModelContainer、ModelContext 与 ModelConfiguration

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

  • ModelContainer 负责创建和管理用于所有 SwiftData 存储需求的实际数据库文件。
  • ModelContext 负责跟踪内存中已创建、修改和删除的所有对象,以便稍后将它们全部保存到模型容器中。
  • ModelConfiguration 确定数据的存储方式和位置,包括使用哪个 CloudKit 容器(如果有)以及是否应启用保存。此配置提供给你的模型容器以确定其行为方式。

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

但并非所有内容都需要立即存储在磁盘上。因为,如果我们总是在磁盘读写我们正在使用的每一条数据,那是非常消耗性能的。所以,SwiftData 会更喜欢将数据从存储读取到内存中,然后从那里使用它,这样速度更快。当我们使用 @Query 或类似方法加载数据时,它会存储在这个模型上下文中以便快速访问。这样我们就可以进行多次更改,并一次性将它们生效,这是更加高效的一种做法。

模型上下文提供了一些非常有用的额外功能,包括撤消或重做更改的能力以及启用或禁用自动保存的能力。因此,模型上下文存储所有内存中的对象和更改,而模型容器则长期存储它。

因为所有 SwiftData 的项目都必须至少有一个模型容器,因此你的主 App 结构中通常会包含这样的代码:

php 复制代码
.modelContainer(for: XXModel.self)

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

Tips:模型容器可以在程序中自由传递,但模型上下文必须保留在创建它们的线程上。

我们可以使用 SwiftUI@Environment 属性包装器从环境中读取此内容:

java 复制代码
@Environment(\.modelContext) var modelContext

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

如何使用 ModelConfiguration 配置自定义的 ModelContainer

当你使用 modelContainer(for:) 获取默认配置时,就意味着 SwiftData 会决定你数据库的存储位置、启用自动保存、禁用撤销等等。你可以重载 modelContainer() 修饰符来修改一些默认配置。

但如果你想完全控制,则需要自己创建一个 ModelConfiguration 对象,然后使用它去创建你的容器。

例如,如果你想将数据库放在 documents 目录下,则可以使用如下代码:

swift 复制代码
@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)
    }
}

手动创建配置的一大优势是,如果你有特别敏感的数据,或者你可能已经发送了一些在任何情况下都不应更改的模板数据,它允许我们完全禁用保存:

ini 复制代码
let config = ModelConfiguration(allowsSave: false)

手动创建配置的优势在于,你可以使用多个 ModelConfiguration 对象来配置单个模型容器。比如,你希望将 Item 存储在一个文件中,而将用户数据存储在另一个文件中,或者其中一个应该备份到CloudKit,而另一个不应该等等。

相关推荐
iFlyCai12 小时前
Xcode 16 pod init失败的解决方案
ios·xcode·swift
Hamm21 小时前
先别急着喷,没好用的iOS-Ollama客户端那就自己写个然后开源吧
人工智能·llm·swift
hxx2212 天前
iOS swift开发--- 加载PDF文件并显示内容
ios·pdf·swift
今天也想MK代码3 天前
基于ModelScope打造本地AI模型加速下载方案
ai·语言模型·swift·model·language model
袁代码3 天前
Swift 开发教程系列 - 第11章:内存管理和 ARC(Automatic Reference Counting)
开发语言·ios·swift·ios开发
袁代码4 天前
Swift 开发教程系列 - 第8章:协议与扩展
开发语言·ios·swift·ios开发
袁代码4 天前
Swift 开发教程系列 - 第9章:错误处理
开发语言·ios·swift·ios开发
iFlyCai4 天前
Swift中的Combine
开发语言·ios·swift·combine·swift combine
一丝晨光4 天前
Objective-C 1.0和2.0有什么区别?
java·开发语言·macos·c#·objective-c·swift·apple
新中地GIS开发老师5 天前
【GIS开发小课堂】高德地图+Three.js实现飞线、运动边界和炫酷标牌
开发语言·javascript·arcgis·前端框架·swift