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,而另一个不应该等等。

相关推荐
Invisible_He2 天前
iOS自定义collection view的page size(width/height)分页效果
ui·ios·swift·collection
无知的前端2 天前
iOS性能优化:OC和Swift实战指南
ios·性能优化·swift
JQShan2 天前
为什么 Swift 的反射像个“玩具”?聊聊 Mirror 背后的设计哲学
面试·swift·设计
东坡肘子2 天前
MCP 崛起与苹果的 AI 框架设想 | 肘子的 Swift 周报 #077
人工智能·swiftui·swift
YungFan3 天前
SwiftUI-国际化
ios·swiftui·swift
xinxiyinhe4 天前
Swift语音助手(苹果生态系统的核心编程语言)
人工智能·swift
潜龙95276 天前
第2.5节 iOS 覆盖率数据的采集
ios·swift·覆盖率
Unlimitedz8 天前
歌曲缓存相关功能
开发语言·ios·缓存·swift
恶霸不委屈8 天前
如何基于ios部署Deep Seek?
python·ios·swift
一牛8 天前
Metal 透视投影
macos·ios·swift