《Core Data应用开发实践指南》一1.1 Core Data是什么

1.1 Core Data是什么

Core Data是个框架,它使得开发者可以把数据当成对象来操作,而不必在乎数据在磁盘中的存储方式。对于Objective-C程序员来说,这很有用,因为他们已经可以通过代码非常熟练地操作对象了。由Core Data所提供的数据对象叫做托管对象(managed object),而Core Data本身则位于你的应用程序和持久化存储区(persistent store)之间。持久化存储区是个通用的术语,指的是像SQLite数据库、XML文件(iOS不支持用XML文件作为持久化存储区)或Binary store(又名atomic store)这种数据文件。由于这些文件在底层硬件重启之后还会保留下来,所以它们是持久的。还有一种持久化存储方式,它的名字非常奇怪,叫做“In-Memory store”。虽说In-Memory store并不是“持久的”,但开发者在用它管理数据时却可以享受Core Data的所有优点,诸如变更管理与数据验证等,另外,其效率自然也是相当高的。
为了把数据从托管对象映射到持久化存储区中,Core Data需要使用托管对象模型,而开发者则可以通过对象图(object graph)来配置应用程序的数据结构。可以把对象图想象成一系列“饼干模型切割刀”(cookie cutter),而托管对象正是用这些切割刀切出来的。对象图里的对象指的是实体,每个实体就好比一把“饼干模型切割刀”,用于制作自定义的托管对象。有了托管对象之后,就可以直接在Objective-C里面操作它们,而无需再编写SQL代码了(笔者假定你使用SQLite作为持久化存储区,因为这是最常用的一种持久化存储方式)。当把数据保存到磁盘的时候,Core Data显然会把这些托管对象映射回持久化存储区里面。
托管对象持有一份对持久化存储区里相关数据的拷贝。如果用数据库作为持久化存储区,那么托管对象可能对应于数据库里某张数据表中的一行。如果用XML文件作为持久化存储区(此方式只有Mac系统支持),那么托管对象可能对应于某个数据元素(data element)里面的一份数据。托管对象可以是NSManagedObject类的实例,但一般情况下,它都是某个NSManagedObject子类的实例。这个问题将在第2章中详细讨论。
所有托管对象都必须位于托管对象上下文(managed object context)里面,而托管对象上下文又位于高速的易失性存储器里面,也就是位于RAM中。为什么需要有托管对象上下文呢?原因之一就是在磁盘与RAM之间传输数据时会有开销。磁盘读写速度比RAM慢得多,所以不应该频繁访问它。而有了托管对象上下文之后,对于原来需要读取磁盘才能获取到的数据,现在只需访问这个上下文,就可以非常迅速地获取到了。但它的缺点在于,开发者必须在托管对象上下文上面定期调用save:方法,以将变更后的数据写回磁盘。托管对象上下文的另一个功能是记录开发者对托管对象所做的修改,以提供完整的撤销与重做支持。
“如果不能把一件事用简单的话说清楚,那就表明你理解得还不够透彻。”这是先贤阿尔伯特•爱因斯坦的一句名言。本书每章均以爱因斯坦的名言开头。Core Data是个比较难学的技术,但这并不是说我们不能把它分解成多个易于理解的小知识点。笔者在编写技术教程和文档的时候,都会遵照爱因斯坦的教诲,尽量用比较好懂的方式把它们写出来,同时也尽量会把内容写得丰富一些。
图1-1直观地描述了Core Data的几个主要概念。

1.1.1 持久化存储协调器

图1-1左侧的持久化存储协调器(persistent store coordinator)里面包含一份持久化存储区,而存储区里面又含有数据表里的若干行数据。设置持久化存储协调器的时候,我们通常选用SQLite数据库作为持久化存储区。另外,也可以选用Binary、XML或In-Memory等形式的持久化存储区。但要注意,Binary和XML格式的存储区是“原子的”(atomic),也就是说,即便你只想修改少量数据,在保存的时候也依然需要把整个文件都写入磁盘。首次将原子的存储区(atomic store)读入内存时当然也会有这个问题。如果数据很多,那么使用这种存储区的问题就比较严重了,因为它会占据宝贵的内存空间。
与原子存储不同,SQLite数据库会在用户提交变更日志时进行增量更新,变更日志也叫做事务日志。由于采用了这种更新方式,所以SQLite数据库的内存占用量相对来说非常小。有鉴于此,开发者一般都会选用SQLite数据库,尤其在把Core Data集成到iCloud的时候,更应该如此。
持久化存储区只应该由Core Data来创建。不应该让Core Data去使用不是由它所创建的数据库。假如需要使用既有的数据,那么应该将其导入Core Data。这个问题放在第8章讨论。
同一个持久化存储协调器可以有多个持久化存储区。把Core Data与iCloud相集成的时候,就可能会出现这种情况。我们可以把不属于iCloud的数据放在一个存储区里,而把属于iCloud的数据放在另一个存储区里。这样既能节省网络带宽,又能节省iCloud存储空间。即便你有两个持久化存储区,也不意味着必须使用两种对象图。Core Data的模型配置允许开发者使用多个独立的存储区,但却采用同一套对象图。在设定Core Data的模型配置选项时,可以指明对象图里的某一部分属于哪个持久化存储区。假如确实想使用多个持久化存储区,那么就不能为这些存储区之间的数据建立“关系”了。Core Data的配置问题放在第15章讨论。
要想创建持久化存储区,需生成NSPersistentStore类的实例;要想创建持久化存储协调器,需生成NSPersistentStoreCoordinator类的实例。

1.1.2 托管对象模型

图1-1的中部是托管对象模型,它位于持久化存储协调器和托管对象上下文之间。顾名思义,托管对象模型是描述数据结构的模型或图示(graphical representation),而托管对象正是以它为基础产生出来的。它与数据库模式(database schema)相似,有时也叫做对象图。要想创建托管对象模型,可以用Xcode来配置实体及实体之间的关系。实体类似于数据库中的数据表模式(table schema)。实体本身并不包含数据,它们只是规定了基于该实体的托管对象应该具有何种特性。实体就是刚才提到的那种“饼干模型切割刀”,正如数据库里的数据表有字段(field)一样,实体也有属性(attribute)。属性的数据类型可以是整数(integer)、字符串(string)或日期(date)。第2章与第4章将会详述这些问题。
要想创建托管对象模型,需生成NSManagedObjectModel类的实例。

1.1.3 托管对象上下文

图1-1的右侧是托管对象上下文,其中包含多个托管对象。托管对象上下文负责管理其中对象的生命期(lifecycle),并且负责提供许多强大的功能,诸如faulting、变更追踪(change tracking)、验证(validation)等。所谓faulting,意思就是用户从持久化存储区中获取数据时,系统只会把需要用到的那一部分获取过来。第10章将详细讨论faulting。变更追踪用于支持撤销及重做功能。验证机制用来确保由托管对象模型所订立的规则。比方说,可以针对实体的单个属性来限定其最小值或最大值,这将在第2章中讨论。
持久化存储区可以有很多个,与之类似,托管对象上下文也可以不止一个。有时我们需要在后台处理任务(比方说把数据保存到磁盘或导入数据),这种情况下可以采用多个上下文。假如在前台上下文(foreground context)上面调用save:,那么用户界面就可能会有“卡顿”(lag)现象,尤其当数据变化较大的时候更是如此。要想避免这个问题,有个简单的办法就是只在用户按下手机Home键时才去调用save:,这时应用程序会转入后台。还有个稍微复杂但却更加灵活的办法,就是采用两个托管对象上下文。请记住,托管对象上下文是存放在高速内存里面的。你可以配置其中一个上下文,令其把数据保存到另一个上下文里。一旦把前台上下文中的数据保存到后台上下文,那么就可将后台上下文中的数据异步地(asynchronously)存入磁盘。这种分段式的做法可以确保磁盘写入操作不会影响用户界面的流畅度。
从iOS 5开始就可以配置多个上下文之间的上下级关系了。子上下文会将它的父上下文视为持久化存储区,而这个父上下文实际上是用来处理各项繁重操作的(例如在后台保存数据等)。这个问题放在第11章深入讨论。
要想创建托管对象上下文,需生成NSManagedObjectContext类的实例。

时间: 2024-09-20 05:41:36

《Core Data应用开发实践指南》一1.1 Core Data是什么的相关文章

《Core Data应用开发实践指南》一第1章 初次尝试Core Data应用程序

第1章 初次尝试Core Data应用程序 如果不能把一件事用简单的话说清楚,那就表明你理解得还不够透彻.-阿尔伯特•爱因斯坦"体验式学习"(kinesthetic learning)或者说"从实践中学习"(learning by doing),是接收并记住信息的绝佳手段.即便对于许多有经验的程序员来说,Core Data也是个相当棘手的话题,于是,笔者就适时地编写了你手中的这本书,它以实践的方式来讲解Core Data.本书不会过早地讲解一些比较难懂的话题,本章只

《Core Data应用开发实践指南》一1.4 为现有的应用程序添加Core Data支持

1.4 为现有的应用程序添加Core Data支持 在Xcode中创建iOS应用程序项目时,可以使用各种起始模板(starting-point template).假如要根据Master-Detail.Utility Application或Empty Application等模板来创建项目,那么只需勾选Use Core Data,即可在项目中使用Core Data.不过,Grocery Dude项目是根据Single View Application模板创建的,它起初并没有包含Core Dat

《Core Data应用开发实践指南》一3.5 通过迁移管理器来迁移数据

3.5 通过迁移管理器来迁移数据 除了通过NSPersistentStoreCoordinator来迁移存储区之外,还可以采用迁移管理器来做.迁移管理器可以使开发者全权掌控迁移过程中创建的文件,从而令他们能够按自己的方式来灵活处理迁移中的各种问题.使用迁移管理器的一个好处就是可以向用户报告迁移进度,使用户知道应用程序哪次会启动得比较慢一些,所以需要耐心等待.虽说迁移过程理应执行得非常快才对,但当数据库比较大.变动比较复杂时,迁移过程就需要耗费一定的时间了.为了使用户界面保持流畅,迁移过程必须在后

《Core Data应用开发实践指南》一1.2 Core Data的适用场合

1.2 Core Data的适用场合 如果应用程序要保存的设置数据太多,以致NSUserDefaults及"特性列表"(property list)这种简单的存储方案无法应付,那么就会出现内存占用量方面的问题.解决办法是直接使用数据库或通过Core Data来间接操作数据库.选用Core Data的好处是,不用再花时间编写数据库接口的代码了.此外,你还将享受性能方面的优势,而且可以使用诸如撤销及验证等强大的功能.假如选择直接使用数据库,那就要花时间去做开发与测试工作,也就是通常所说的&

《Core Data应用开发实践指南》一3.1 修改托管对象模型

3.1 修改托管对象模型 在应用程序的进化过程中,其托管对象模型也可能需要改变.对于一些比较简单的修改,诸如设定属性的默认值.设定验证规则.使用获取请求模板等,是可以直接实施的.而对于另外一些更为结构化的(structural)修改,则需先把持久化存储区迁移到新的模型版本才行.假如没有提供迁移数据所需的映射与设定,那么应用程序就会崩溃.为了继续构建范例程序,需要把上一章中的代码添加到Grocery Dude项目中.或者可以去http://www.timroadley.com/LearningCo

《Core Data应用开发实践指南》一2.2 添加托管对象模型

2.2 添加托管对象模型 在第1章中,我们通过CoreDataHelper.m文件里的mergedModelFromBundles方法初始化了托管对象模型.然而现在的问题是:项目里根本就没有模型可用!如果连模型都没有的话,那Core Data就彻底失去意义了,所以,我们这个时候应该创建模型文件.模型文件一般会含有"对象图",而对象图则用来表示应用程序的数据结构以及其他一些可以简化应用程序开发的东西,我们稍后再来解释.请按下列步骤修改Grocery Dude,以便添加数据模型文件: 在现

《Core Data应用开发实践指南》一1.3 创建Grocery Dude项目

1.3 创建Grocery Dude项目 Grocery Dude是个运行在iPhone上的范例程序,在学习本书的过程中,你将了解到它的制作流程.学会了Core Data中的某个特性或某项开发技巧之后,你可以将其运用在Grocery Dude程序上面.到了本书收尾的时候,你将会制作好一款功能完备而且运行速度很快的Code Data程序,它能够同iCloud紧密地集成在一起.假如你现在就想直接看看成品,那可以去App Store下载Grocery Dude.请注意,Grocery Dude是专门为

《Core Data应用开发实践指南》一3.3 轻量级的迁移方式

3.3 轻量级的迁移方式 把新模型设为当前版本之后,必须迁移现有的持久化存储区,只有这样,才能正常使用新模型.这是因为,持久化存储区协调器会试着用新版的模型来打开原有的存储区,但由于原有的存储区是用旧版模型创建的,所以该操作会失败.在向NSPersis-tentStoreCoordinator添加存储区的时候,只需将下列选项放在NSDictionary里传过去,即可自动完成存储区的迁移工作:如果传给NSPersistentStoreCoordinator的NSMigratePersistentS

《Core Data应用开发实践指南》一2.12 后端SQL的可见性

2.12 后端SQL的可见性 如果只在控制台的日志中查看Core Data所输出的结果,那么意义并不算太大.你知不知道这些事情背后究竟发生了什么?Core Data对持久化存储区中的数据到底进行了哪些操作?这些操作是否恰当?为了提供无缝的Core Data体验,系统都生成了哪些SQL查询语句?每次在模拟器中运行程序的时候,是不是会插入重复的对象? 有个极其详尽的调试选项可以提供足够的信息,告诉你这些操作背后所发生的事情,从而令你知道上述那些问题的答案.这个调试选项会把系统自动生成的SQL查询语句

《Core Data应用开发实践指南》一2.13 获取托管对象

2.13 获取托管对象 想操作托管对象上下文中的现有数据,就必须先把它获取(fetch)过来.假如待获取的数据没有放在上下文里,那么Core Data会从底层的持久化存储区里把它拿出来,这个过程对开发者来说是透明的.要执行获取操作,就得有NSFetchRequest实例,该实例会返回NSArray,这个数组里面的元素都是托管对象.在执行获取操作的时候,NSFetchRequest会根据特定的实体,把每个托管对象都放在NSArray这个数组中,并将其返回给调用者.用SQL数据库领域的术语来说,获取