Core Data是苹果公司管理iOS应用程序中持续存在的对象图的主要框架,与其强迫开发者编写原始SQL或管理文件序列化,还不如提供高层次面向对象的界面,处理存储,变化跟踪和数据模型制作的复杂性. 每个使用本地数据的iOS开发者都应该了解Core Data的能力和最佳做法,在不牺牲性能的情况下构建反应灵敏,数据丰富的应用软件.

理解核心数据结构

Core Data 不仅仅是一个数据库。 它是一个对象图管理框架, 可以将数据粘着到磁盘, 但它也管理内在对象关系、 撤销管理和验证。 架构围绕四个关键组件, 它们共同组成通常称为 [[FLT: 0]] 的 Core Data stack [[FLT: 1] 。

核心数据堆栈

每个核心数据执行都需要一组特定对象,按定义的顺序链接。堆栈由以下部分组成:

  • 管理对象上下文(NSManaged ObjectContext): 开发者与管理对象一起工作的抓图。所有更改在保存到持久存储之前,都发生在上下文中。
  • 恒定存储协调员(NSPERSYENTStore Consultanted): 充当上下文与实际的恒定存储之间的桥梁,它调解了访问并确保数据的完整性.
  • 管理对象模型(NSManaged Object Model): 描述数据计划中的实体,属性和关系,通常在.xcdatamodel文件中以视觉方式定义.
  • 活性存储器: 实际存储机制,可以是SQLite,二进制,也可以是内置. SQLite是生产应用的默认.

现代iOS开发经常使用类,该类自动创建和配置整个堆栈,这可以移除锅炉板,减少配置错误的可能性.

在您的工程中设置核心数据

将核心数据添加到iOS项目需要多个刻意步骤,每个步骤都为数据管理奠定基础。这一过程首先要创建数据模型文件,然后定义您的实体,最后将堆栈与您的应用生命周期整合。

创建数据模型

开始使用 [[FLT: 0]] 数据模型[模板(extension.xcdatamodeld) 向您的 Xcode 项目添加新文件。在此视觉编辑器中,您定义实体(相当于表格)、其属性(列)以及与其他实体的关系。您还可以指定数据类型、默认值、验证规则和索引选项,以优化查询性能。

界定实体和关系

每个实体代表您应用程序管理的对象类型, 如用户、 任务或产品。 属性定义了该实体的特性( 名称、 价格、 日期等 ) 。 关系连接实体, 使 Core Data 能够跟踪对象图表并自动传播删除或更新。 例如, “ Person” 实体可能与“ Phone Number” 实体有一对多的关系, Core Data 可以在任意方向获取 。

在设计关系时,注意删除规则. 选项包括Nullify, Cascade, 和 Deny. 选择错误的规则会导致数据意外丢失或孤零零的记录. Cascade通常适合父母与子女的关系,而Nullify对可选协会则效果良好.

生成由NS管理的对象子类

一旦您的实体模型完成, Xcode 可以自动为每个实体生成 Swift 类。 这些子类继承了 [[FLT: 1] , 并包含您定义的属性和关系 。 从 Xcode 8 开始, 建议的方法是选择“ 代码” 作为 [[FLT: 0]] 类定义 [[FLT: 1] (默认), 它将生成的文件保存在生成的数据文件夹中 。 或者, 您可以选择“ 手动/ 无人” , 并创建自己的子类, 在添加自定义方法或计算属性时有用 。

执行 CRUD 操作

堆栈到位后, 您可以使用 [[ FLT: 2]] 插入、 获取、 更新和删除管理的对象。 所有操作必须在上下文中执行, 更改只有在成功调用后才会持续 。

创建和保存对象

要插入新对象, 请使用 [[ FLT: 4]] 并设置其属性。 在所有更改后, 请拨打 [ [ FLT: 5] 。 总是将保存调用包在一个 [ [ FLT: 6] 块中, 以优雅地处理错误, 特别是在用户启动的动作中 。

正在以示意图和排序描述符获取数据

是查询对象的主要机制。您可以使用[(例如]]]来限制结果,并用来命令结果。核心数据还支持复合上游、子加密和急切地获取关系。对于大型数据集,总是用[来限制获取大小,并考虑使用来减少内存使用。

更新和删除

更新对象与在上下文中修改其属性一样简单; Core Data 自动跟踪更改。 要删除, 请调用 ]。 请记住保存上下文。 对于批次删除, 请使用在不将对象装入内存的情况下直接在持久性存储器中运行的 [[FLT: 14]] , 从而显著改进性能 。

生产-准备核心数据的最佳做法

即使配置良好的核心数据堆栈,如果不仔细处理,也可能成为错误的瓶颈或源头。遵循既定模式,确保您的应用始终具有响应性、稳定性和可扩展性。

线条安全和货币

核心数据上下文默认不是线程安全。 绝不在线程之间共享上下文。 相反, 在 [[FLT: 16] ] 上使用 [[FLT: ] ] 方法创建背景操作的私密队列上下文。 在访问主线线上的对象时, 请使用 [[FLT: 17] 或 [[FLT: 18]]] 来确保线程封装。 对于 SwiftUI , [[FLT: 19] 属性包装器会自动观察到主上下文的变化, 但重抓取件仍应卸载到背景上下文 。

版本和迁移

随着您的应用的演进, 您的数据模型会改变 — 添加属性, 重命名实体, 或改变关系。 核心数据支持两种类型的迁移 : [[ [FLT: 0]]] 轻量级迁移 [[ [FLT: 1] 和 [[FLT: 2] 海关迁移 [[[FLT: 3]] 。 轻量级迁移处理简单的改变( 添加属性, 改变可选性, 重命名属性并带有标识符) , 如果您在添加存储时通过选项, 则自动进行。 对于复杂的转换, 请创建绘图模型并执行 [[ [FLT: 20] 子类。 总是彻底测试迁移, 因为失败的迁移会损坏用户数据 。

性能优化

高效的核心数据性能始于数据模型设计。 在通常出现在上游的属性上使用 索引 。 当只需要子集时, 避免获取整个对象图表; 反之, 请使用 和 ] 。 核心数据支持 [ 故障, 在一个对象属性在访问之前不会加载。 您可以在表卷轴时预先调试与 [ 的关系, 以避免“ 故障- 发火” 。 对于只读数据, 请考虑使用 [ 获取返回的字典, 而不是完全管理的对象 。

处理错误

每次获取、保存和删除操作都可能失败。 总是将这些调用夹在 [[FLT: 25] ] 块中, 并向用户显示有意义的错误消息。 保存失败经常由于验证错误或约束性违反而发生, 所以仔细检查错误。 Core Data 错误对象包含多个内在错误, 您可以通过这些错误进行排列以提供具体的反馈。 对于批量操作, 请适当处理 [[FLT: 26] —— 注意批次删除不会自动级联, 因此可能需要手动处理相关的对象 。

将核心数据与 SwiftUI 整合

SwiftUI 通过属性包和环境值为核心数据提供一等支持。 包装器在数据变化时自动观察主上下文并刷新视图。 您可以在属性声明中直接配置排序描述符和上游。 对于更细的颗粒控制, 请使用 [[FLT: 28]] 将管理对象上下文注入环境。 在为视图模型与 QQQObServed Object 或 QQQS State Object 合作时, 要确保视图模型在进行重操作时能够引用背景背景 。

SwiftUI还简化了上下文上的撤销管理:设置,SwiftUI会自动与系统的撤销/重做手势集成.

核心数据与其他持久性选项

虽然核心数据是iOS本地存储最成熟和最综合的解决方案,但它并不总是最佳的选择。用替代品比较它:

  • 用户默认:适合用户偏好小,但不适合复杂或大数据.
  • Realm:[] 提供更简单的API和自动反应更新,但增加了依赖性,没有像SwiftUI那样深入的集成.
  • Raw SQLite:对非常大的数据集或复杂的查询给予最大控制和性能,但需要手动管理连接,迁移,以及线程.
  • 云Kit + 核心数据: 对于需要iCloud同步的应用程序,苹果公司的 桥接核心数据和云Kit,自动同步本地对云的更改.

对于大多数需要结构化数据,关系,以及离线能力的标准iOS应用,由于Core Data与平台的无缝整合以及持续的苹果支持,因此Core Data仍然是推荐选择.

结论

Core Data提供了一种对象图管理系统,可以消除持续存储、变化跟踪和关系管理的复杂性。 通过理解其架构 — — 从管理对象上下文到持续容器 — — 并遵循已经证明的货币、性能和错误处理做法,开发者可以建立既强健又反应灵敏的应用程序。无论是构建一个简单的to ⁇ do列表还是数据密集型的企业应用程序,掌握Core Data都是一种宝贵的技能,可以解锁iOS上有效的本地数据管理。

进一步研究,可参阅 pple核心数据文档,核心数据编程指南,以及社区资源,如 Ray Wendelich 由图多尔斯编写的核心数据[,用于手动练习和对移徙和货币等先进专题的更深入的见解.