Core Data Basics
本篇描述了 Core Data 的基本架构 和 使用该框架的方式。
Basic Core Data Architecturehttp://write.blog.csdn.net/postedit
在大多数应用中,你需要打开一个包含了一些归档对象的文件,然后至少保持对一个根对象的引用。然后当你对这些对象的更改操作做撤销或追踪时,你还需要归档这些对象。例如,在一个员工管理应用程序中。您需要一种方式来打开一个包含 employee 和 department 对象存档信息的文件,然后你还要至少引用一个根对象,例如 employee 对象数组(如图1),你也需要能够将所有 employee 和 department 归档到一个文件。图1
你得负责管理上面提出的全部或部分问题。例如,在OS X桌面应用,Cocoa 文档体系提供了一个 应用程序结构 和 一些功能帮助减轻这项负担,但是你仍然不得不写一些方法用来去归档数据、解档数据、追踪模型对象、撤销操作等。
使用CoreData框架,大多数的功能将会自动提供给你,主要是通过一个被称之为‘被管理对象上下文’(managed object context)的对象实现。managed object context 提供了一个途径让你使用那个被称之为‘ 持久化堆栈(persistence stack)’的框架底层对象集合,这些对象是用来在应用程序与外部数据之间提供访问通道。(图2)
图2
Core Data并不局限于基于文档的应用程序,你可以开发一个没有任何界面的并且使用Core Data的功能。其他应用程序也同样适用。(see Core Data Utility Tutorial)
Managed Objects and Contexts
你可以认为 managed object context 是一个智能的便笺本,当你从一个persistent store中获取对象时,CoreData 会将对象的临时拷贝记录在便笺上,便笺上的所有对象便会形成一个对象图 或 对象图集合(object graph or a collection of object graphs),然后只要你喜欢你就可以任意修改这些对象。除非你保存这些改动,否则persistent store中的数据是不会改变的。连接到Core Data框架的模型对象(Model object)被称之为 managed object。 所有的 managed objects 必须在 managed object context 中注册。你可以使用 managed object context 在对象图上进行添加 或 删除对象。managed object context 将会追踪你对对象做的任何改动,不管是对象的属性(attributes)还是对象之间的关系(relationships)。通过对变动的追踪,managed object context 将能够提供给你撤销和重做的支持。同时,当对象之间的关系发生变动时,CoreData能够保持对象图的完整性。
如果你打算保存你所做的改动, managed object context 可以确保你的对象是处于有效状态。然后改动将会被写到 persistent store 中,如果你创建了一个对象那么将会在persistent store中添加一条记录,如果你删除了一个对象,同样的也会在persistent store中删除一条记录。
在应用程序中,你可能会拥有不止一个managed object context,persistent store 中的每一个对象在给定的context中最多有一个与之相关联的 managed object (更多细节,参见 Faulting and Uniquing )。从不同的角度考虑这个问题,一个在persistent store(persistent store) 中给定的对象可能同时在多个 context 中被编辑。但是每一个 context 中的对象都有一个与源对象相对应的 managed object ,并且每一个 managed object 都被单独的编辑。这种状况将会在保存对象时导致不一致,Core Data提供了多种处理此种情况的方式。(参见 Using Managed Objects))
Fetch Requests
你需要创建一个 fetch request 用来从 managed object context 中获取数据。一个 fetch request 对象描述了什么数据是你想要的。例如 ‘所有的员工’ 或 ‘所有在Marketing部门的按薪水由高到低排列的员工’。一个 fetch request 有三个部分,第一,最少指定一个实体名称(entity name,by implication 你只能一次获取一个类型的实体)。第二,可以指定一个predicate对象,这个 predicate 对象指定了被检索的对象必须满足的条件。第三,还可以包含一个 sort descriptor 对象数组,这个数组指定了对象展示的顺序。如图3图3
当你向一个 managed object context 发送一个 fetch request ,系统将会从与persistent stores相关联的数据源中返回满足你这个请求的对象。因为所有的 managed object 都必须在managed object context中注册,所以通过 fetch request 检索出来的对象都会自动在 fetch request 对应的context中进行注册。回忆一下,persistent store 中的每一个对象在给定的context中最多有一个与之相关联的 managed object,如果一个 managed object context 已经包含了要检索的对象的相对应managed object,那么当前的那个managed object将会作为此次fetch request返回数据。
Core Data框架是尽最大努力提高性能的。Core Data框架是需求驱动的,所以不要创建比你实际需要更多的对象。对象图也没有必要表示出在persistent store中的所有对象,简单的指定一个persistent store将不会在managed object context中加入任何数据对象。当你检索 persistent store 中对象的子集时,你只会获取到你请求的那些对象。如果你遵循了一个没有检索出来的对象的关系,这个对象将会自动检索出来。如果你停止使用一个对象,默认情况下,这个对象将会被销毁。(当然,这和从对象图中移除这个对象不一样)
Persistent Store Coordinator
如前面所说的那样,CoreData 框架中用来作为应用程序与外部存储数据之间访问通道的对象集合被称之为‘ 持久化堆栈( persistence stack ) ’,栈的顶部是managed object contexts,栈的底部是 persistent object stores,managed object contexts 和 persistent object stores 之间则是 persistent store coordinator( 持久化存储助理)。实际上,一个persistent store coordinator定义了一个堆栈,coordinator目的是给 managed object contexts 提供了一个封装,让一组persistent store 看起来就像一个 聚合存储(aggregate store),A managed object context can then create an object graph based on the union of all the data stores the coordinator covers(这句不太会翻译)。
一个 coordinator 只能与一个 managed object model 关联,如果你想要把不同的实体放进不同的存储中,你必须通过定义managed object models的配置,对实体模型进行划分。(详见:Configurations)
图4中展示了一个例子:employees 和 departments 存储在同一个文件中,customers 和 companies 则存储在另外一个文件中。当你检索对象时,这些信息将会自动的从相应的文件中获取,当你要保存的时候,这些信息也会归档到相应的文件中。
图4
Persistent Stores
一个给定的持久化对象会与一个单独的文件 或 其他的外部存储关联,这个对象负责外部存储中的数据与managed object context中的对象的映射。通常只有当你指定一个新的与应用程序相关联的外部存储位置的时候,你才会操作 persistent object store(例如当用户打开或保存一个文档)。大多数情况下,你都是通过 managed object context 使用Core Data框架。
你的应用程序的代码,特别是与managed objects相关的应用程序逻辑中,不应该做任何关于persistent store中数据是否存在的假设。CoreData 提供了对一些特定格式文件的本地化支持,你一可以根据你的应用程序选择性使用。如果在某个阶段,你决定使用另一个不同格式的文件,你的应用程序结构则不需要做改变。此外,如果你的应用程序进行了适当的抽象与封装,后期你将会很轻松的对应用使用该框架的地方进行改进。例如:最开始时,应用只是从本地文件中读取数据,如果应用中没有假定数据的来源,那么在后期如果你需要添加一个新的远程persistent store时,将不会有代码的修改。
Important:虽然 SQLite 是CoreData支持的 persistent store类型中的一种,但是 Core Data 并不能管理那些外部的 SQLite 数据库。Core Data 必须自己创建和管理这些数据库。(更多关于store types的信息,参见Persistent Store Features)
Persistent Documents
你能够通过编程的形式创建和配置 persistence stack。在许多情况下,你只是简单的想创建一个能够读写文件的document-based应用。NSPersistentDocument (
目的就是让你简单的使用 Core Data 框架。默认情况下,一个NSDocument
的子类)NSPersistentDocument
实例会创建一个自己的随时可用的 persistence stack,它包含了一个 managed object context 和一个单独的 persistent object store。这种情况下就会有一个document 和 外部数据存储之间的一对一的映射。
NSPersistentDocument
提供了一些访问 document 的 managed object context 的方法,也提供了标准的 NSDocument
方法的实现,使用这些方法用来读写使用了Core Data 框架的文件。默认情况下你不需要写任何代码去处理对象持久化。持久化document的撤销功能是包含在 managed object context 中的。
Managed Objects and the Managed Object Model
为了管理对象图 和 支持对象持久化,Core Data 需要对它操作的对象有一个比较丰富的描述。managed object model 是一种模式,它表示了对应用中所有托管对象、实体的描述。如图5。通常你会使用 Xcode的 Data Model Design 工具以可视化的形势创建 managed object model。(如果你愿意,你也可以在运行时以通过编程的方式创建)
图5
managed object model 是实体描述对象的集合,每个实体描述对象包含了实体的名称、应用中对应的类的名称(该名称不一定要与实体名称相同)、attributes 、relationships。attributes 和 relationships 分别表示 attribute 和 对象之间的关系,如图6
图6
Managed objects 必须是 NSManagedObject 或 NSManagedObject 子类的实例。NSManagedObject 能够表示任何实体。它使用一个私有内部存储维护其 properties 并且实现作为managed object 需要的所有基本操作。managed object 拥有一个实体描述实例的引用。它通过实体描述能够获取自身的元数据信息,这些信息包括它表示的实体、attributes 和 relationships。你也能够通过创建NSManagedObject子类的方式去添加额外的操作。