《驾驭Core Data》系列教程综合了《Core Data for iOS》,《Learning Core Data for iOS》,《Core Data Programming Guide》,以及相关的博客资料。共包含14章内容。希望本系列教程能对学习Core Data的iOS开发者有所帮助。

本文由海水的味道编译整理,请勿转载,请勿用于商业用途。

      当前版本号:0.0.5 

第一章 Core Data概述

Mac OS X 10.4 Tiger首次引入Core Data,旨在为存储与获取应用程序的模型数据提供统一的框架。Mac OS X 10.5 Leopard又对Core Data进行了提升。在这之后,苹果公司又将Core Data应用于iPhone OS 3.0及以上版本的iOS设备上。虽然Core Data在一定程度上缓解了处理模型数据的复杂性。但掌握Core Data 也绝非易事。

本章首先简要介绍了Core Data的发展历史,然后从较高层面对Core Data进行概括,在最后一节,列举了一些iOS开发者如何利用Core Data提供的功能简化模型处理的真实案例。

Core Data的前身

当前Core Data的绝大部分功能之前是以企业对象框架EOF(Enterprise Objects Framework)存在的。EOF由NeXT公司开发。作为WebObjects一部分,它被用于访问存储在关系数据库中的数据。为了节省开发者编写访问数据库的底层代码。EOF利用对象关系映射技术,为访问面向对象的类结构数据提供了一套机制。

相对于需要为访问数据库与获取数据库表行和表列编写代码,对象关系映射将数据库表映射为类,表列映射为类的属性,表行映射为类的实例。因为EOF在后台处理了这些映射细节,所以你可以改变底层数据库或类下的存储机制而不用担心修改访问类的代码。

Core Data的今世

Core Data大部分功能都脱胎于EOF,但需要强调一点,Core Data本身既不是数据库也不是数据库访问框架。相反,Core Data是一个完整的数据模型解决方案。它允许对象图(object graph)的可视化设计;使用代码创建和查询对象图中的对象;以及使用代码将对象持久化到磁盘。

虽然一般使用Core Data是将对象存储到SQLite数据库,但使用非数据库存储方式如XML文件、二进制文件,甚至是为满足具体需求而完全由开发者自行创建的持久化存储文件也是允许的。在桌面平台,苹果公司提供了SQLite、XML以及二进制存储方式供你选择。而在iOS平台,因为不支持XML存储方式,所以大部分iOS app会选择SQLite存储。

另一点需要强调的是:Core Data支持的模型可用于存储所有类型的数据。并不一定要求是通常认为的数据库风格数据。Core Data可以存储诸如手术中医生的病人记录、公司财务应用的发票和财务信息。使用Core Data存储iOS绘图应用的矢量图形信息;社交应用的账号和搜索记录、游戏记录和需要持久化的状态信息,也是极其简单。

为什么使用Core Data

Core Data框架提供了一种稳定且快速访问数据模型的方式。它不需要大量的内存与处理器开销。

你可能会想,“我只是想持久化一些数据,何必这么劳师动众?”,当然,你可以使用类似FMDB的包装类编写自己的数据库接口,一开始这些接口可能会工作的很好。但是当你的需求发生了变更或者你需要加入新的功能,比如需要在设备之间保持数据同步;不影响界面响应的情况下,处理大量数据的导入;保证在旧的iPhoen设备上流畅运行前提下,支持撤销和数据验证,诸如此类的复杂需求。

幸运的是,所有这些复杂的工作已经包含在了Core Data框架之中。即使你的app并不需要处理成千上万的数据,使用Core Data来保证软件的扩展性与性能也是非常有价值的。

关系管理

由于Core Data前身是为了方便关系型数据库的使用,所以Core Data的特色之一就是它可以管理对象之间的关系。使用XCode的可视化数据模型设计器,对象之间的连接关系可以使用一对一、一对多或多对多的形式定义。

你可以对定义的关系设定规则。有一些特殊的关系必须要对其定义规则(比如一笔财务交易必须关联一个银行账户;一家公司必须至少有一位经理)。当在保存时,新建的对象被保存到底层的存储文件中。如果对象没有满足既定的规则,框架将会拒绝接受此对象,由此以维护对象图的完整性。

类似地,如果你改变了关系的一端,Core Data会自动处理关系另一端的变化。比如将A医生的一位病人转调给B医生。则两位医生相关联的病人列表都将相应地被自动更新。当数据模型中提供的关系规则被正确地设定,则删除了财务应用中的一个银行账户,所有与该账户相关的财务交易也会被自动删除。

NSManagedObject对象与数据验证

当使用Core Data时,你所操纵的对象被称为NSManagedObject对象,标准的NSManagedObject对象除了之前提到的关系管理功能外,还支持对数据的验证。

对象的验证发生在对象的属性上。你可以对模型中的单个属性设置规则。比如一个人的薪水不可以低于0。或者在多个属性之间设定自定义规则。比如病人如果小于特定的年龄则不可能会有孩子。

同样,如果你尝试使用一个无法通过验证测试的值更新对象,Core Data就会报错,以防止你保存不正确的数据。

撤销与状态管理

Core Data会自动地维护一个撤销栈。如若必要,即使对象已被保存到持久化存储文件,对对象的修改也可以被撤销。同样,这也是自动完成的,你不需要编写任何的撤销代码。

由于桌面平台与移动平台的底层框架代码完全相同,所以一旦你学会了如何在iOS平台使用Core Data,你就已经扫清了在桌面平台使用Core Data的大多数障碍。话虽如此,iOS平台相对于桌面平台的Core Data,实际还是会有一些区别。

iOS平台与桌面平台的Core Data之间的区别

一个最大的区别是iOS平台的Core Data不支持绑定(Bindings)。在桌面平台,绑定利用KVO和KVC保持UI项与模型对象或属性之间的连接。使用绑定技术,你可以在桌面平台构建强大的Core Data应用程序而无须编写任何代码。你只需简单地使用XCode的Interface Editor绑定类似表格视图和文本域UI项,通过对象和数组控制器自动从Core Data存储区分批提取NSManagedObject对象。

而在iOS平台,Core Data对这类即时满足(instance gratification)风格的绑定功能不做支持。相反的,你需要直接使用Core Data框架的各部分功能为用户界面提供相关数据。

NSFetchedResultsController

为了优化数据提取的过程,苹果公司单独为iOS平台的Core Data引入了NSFetchedResultsController类。顾名思义,NSFetchedResultsController(在第五章将会有一个完整的章节讨论该类)被用作控制器层的类,帮助视图与从持久化存储文件提取的数据之间的交互。它主要是用来充当UITableiView的数据源,负责调整UITableiView行与节(section)的显示数目,以及为各表格行提供内容。

NSFetchedResultsController以尽可能高效的方式消除一次性将所有查询结果载入内存的需要。它会自动处理当前不会被访问到的对象。这让处理大数量的对象更容易。如果你在表格视图中使用NSFetchedResultsController对象显示一个包含上千个对象的容器。那么在特定时刻,只会有一小部分对象将被载入内存。

Core Data案例研究

MoneyWell for iPhone

MoneyWell是一个个人理财应用,用于追踪个人的收支情况与管理现金流,用户通过查看所有可用的收支类别来管理可用的现金。当MoneyWell还在设计中时,Mac OS X Tiger与Core Data还刚发布不久。MoneyWell中的数据关系相当复杂,而Core Data的使用极大简化了模式设计与开发过程。2007年10月17日,Steve在苹果网站的一封公开信上宣布适用于iPhone设备的SDK将会于2008年2月提供给第三方开发商。听闻这一消息后,我们相信如果将MoneyWell一直到iPhone上,它将会是iPhone设备上最棒的理财应用。可问题是第一次发布的Core Data for iOS还不对开发者开放。所以我们推迟了MoneyWell for iPhone的开发。我们相信苹果公司会将Core Data迁移到移动设备上。果不其然,Core Data在iOS 3.0 SDK中被引入。

Core Data for iOS的出现解决了许多开发难题。比如在MoneyWell for iPhone中创建模型层只需简单地复制Xcode数据模型到新的项目。此外,MoneyWell的Mac版本和iOS版本之间可以共享相同数据文件,这让我们可以使用已有的所有测试文档。苹果公司对iOS平台Core Data的性能改进也让我们受益良多。贯穿于开发过程中的数据处理、数据持久化,以及对象图维护已变得非常简单,我们可以专注于更重要的问题,比如创建更好的用户体验。而对于我们来说,最大的获益无疑是Core Data结合UITableView的使用。想象一下,一个典型的用户可能有积累数年的财务数据,这无疑会消耗移动设备的大量内存。如果没有Core Data,我们不得不编写复杂的分页算法或者大量的SQLite查

询。而使用Core Data,我们可以查询一个分类的交易,并且依靠Core Data智能的数据分页能力,可以按需将数据载入或载出内存。

使用Core Data轻松地节省了我们五个月甚至更多的开发时间。

Kevin Hoctor and Michael Fey, No Thirst Software LLC

Calcuccino

Calcuccino是一个程序员专用计算器,它使用iPhone的菜单和滑动手势改善传统计算器功能,且配备了让输入更快速可靠的大按钮。

在Calcuccino中使用Core Data的这项决定不是特别明显,因为Calcuccino没有处理大数据量的需要,但是它需要存储用户的计算历史,以让用户可以在以后可以查阅或者重用。同时软件也需要保持当前的计算状态,当用户从另一个应用切回当前应用,它的计算状态应该被恢复。在Core Data之前,这些需求我们是通过使用XML文件持久信息实现的,但这导致需要为处理XML编写许多代码。

在Xcode中Core Data提供了一个数据模型设计器,它被用来构建诸如存储历史步骤的HistoryStep实体和当前计算状态的OpStep实体。对于计算引擎本身,我们定义了一个CalcValue类,该类是一个基本的数字类型(类似于Cocoa的NSNumber类,不过它新增了整数位数和格式化功能),CalcValue的使用贯穿整个项目。GeneralValue实体实例生成的所有CalcValue实例都被存储在Core Data存储区。

Calcuccino的数据模型很好的展现了应用的需求。应用中有一个处理Objective-C类与Core Data之间交互的CalcStore类。由于Objective-C与实体之间的映射仍然需要编写映射代码,这点让我有些失望。这和将Objective-C类转换为XML或将XML映射为Objective-C类的代码没有什么不同。我们迟疑是否需要从原始的NSManageObjects转向可以减少映射代码的自定义类。

以我们使用Core Data的经验来说,如果问我们是否还会使用Core Data?答案是肯定的。我们相信这个决定是正确的。当需要在表格视图中展示保存在Core Data中的计算历史数据,并且按天进行分组时,只需要使用NSFetchedResultsController几行代码就可以轻松完成,这真是太省心了。一旦我们开发了一些Calcuccino版本,我们就需要使用Core Data的版本控制功能来进行数据库的版本控制。我们希望我们将继续相信我们做出了正确的决定。

Andy Dean, Cambridge Coders Ltd

美联社新闻Associated Press

当要着手开发Associated Press的时候,我知道使用Core Data是一种必然。如果尝试使用其他类型的持久层,我们所处理的数据量则太多了。另外基于对异步数据传输的需求,Core Data无疑是最佳选择。

通过设置一个直接将数据映射到Core Data模型的数据解析器,然后在后台线程中保存这些数据,用户体验就可以大幅提升。

当我们开始设计应用时,我们了解到与服务器通讯的接口将被多个应用使用,所以我们将接口设计成了一个单独库。通过这样的设计只需要将数据加入到Core Data持久层。我们能够为任何在其上构建的应用提供一个简单通用的接口,每一个应用只需关注Core Data中底层数据的变化。这样做能够保持app和库之间的接口代码的最小的耦合。

实际上现在我们已经使用该库超过一年,没有出现什么问题。同时也应用在十多个应用中,表现非常不错。如果我们使用其他的持久化引擎,我怀疑我们还需要面对性能与内存问题的挑战。

Marcus S. Zarra, Zarra Studios LLC

《驾驭Core Data》 第一章 Core Data概述的更多相关文章

  1. javaSE习题 第一章 JAVA语言概述

    转眼就开学了,正式在学校学习SE部分,由于暑假放视频过了一遍,略感觉轻松,今天开始,博客将会记录我的课本习题,主要以文字和代码的形式展现,一是把SE基础加强一下,二是课本中有很多知识是视频中没有的,做 ...

  2. 第一章、Django概述

    目录 第一章.Django概述 一.了解软件开发架构 二.HTTP协议 三.响应状态码 四.请求方式 五.基于wsgiref模块 六..动静态网页 七.python三大主流web框架 八.安装Djan ...

  3. 第一章 Windows内核概述

    第一章 Windows内核概述 这一章节描述了Windows内核知识中最重要的几个概念,这些话题在这本书之后会有更详细的描述,那些会与当前的主题密切相关.要确保你理解这个章节的概念,因为这些概念构成了 ...

  4. Learning From Data 第一章总结

    之前上了台大的机器学习基石课程,里面用的教材是<Learning from data>,最近看了看觉得不错,打算深入看下去,内容上和台大的课程差不太多,但是有些点讲的更深入,想了解课程里面 ...

  5. Java核心技术(Java白皮书)卷Ⅰ 第一章 Java程序设计概述

    第1章 Java程序设计概述1.1 Java程序设计平台 具有令人赏心悦目的语法和易于理解的语言,与其他许多优秀语言一样,Java满足这些要求. 可移植性 垃圾收集 提供大型的库  如果想要有奇特的绘 ...

  6. [编程笔记]第一章 C语言概述

    //C语言学习笔记 第一讲 C语言概述 第二讲 基本编程知识 第三讲 运算符和表达式 第四讲 流程控制 第五讲 函数 第六讲 数组 第七讲 指针 第八讲 变量的作用域和存储方式 第九讲 拓展类型 第十 ...

  7. 《C#并发编程经典实例》学习笔记-第一章并发编程概述

    并发编程的术语 并发 同时做多件事情 多线程 并发的一种形式,它采用多个线程来执行程序. 多线程是并发的一种形式,但不是唯一的形式. 并行处理 把正在执行的大量的任务分割成小块,分配给多个同时运行的线 ...

  8. Node入门教程(2)第一章:NodeJS 概述

    Node 概述 什么是 Node Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...

  9. 数据库系统实现 第一章 DBMS实现概述

    DBMS提供的能力 1)持久存储 DBMS在灵活性方面比文件系统要好,同时支持对非常大量数据的存储 2)编程接口 3)事务管理 DBMS支持对数据的并发存取,即多个不同的进程(称作事物)同时存取操作, ...

随机推荐

  1. js对象深潜拷贝(从requirejs中抠出来的)

    var op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty; function isFunction(it ...

  2. 基于PXC的MySQL高可用环境简单部署

    PXC简介 Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法. 1.集群是有节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上. 2.每个节 ...

  3. javascript中的时间处理

    var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-???? ...

  4. WindowsPhone8解锁提示IpOverUsbSvc问题

    问题如图: 一般都是系统未启动或者未安装该服务. 1.使用sc命令查询是否存在IpOverUsbSvc服务 Cmd执行Sc query IpOverUsbSvc 结果如下,如果可以找到服务,state ...

  5. Linux 网络编程二(Socket创建)

    TCP通信 一个程序使用套接字需要执行4个步骤. --分配套接口和初始化 --连接 --发送或接收数据 --关闭套接字 涉及到的调用包括socket.bind.listen.connect(阻塞线程) ...

  6. C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)

    反射以及Attribute在ORM中的应用 一. 反射什么是反射?简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等.反射有什么用呢?反射不但让你在运行 ...

  7. [CareerCup] 9.6 Generate Parentheses 生成括号

    9.6 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-p ...

  8. 实践:VIM深入研究(20135301 && 20135337)

    目录 一.基本知识 1.vim模式介绍 2.三种常用模式的切换 二.Vim文档编辑 1.vim重复命令 2.游标的快速跳转 3.复制粘贴和剪切 4.删除文本 5.字符的替换及撤销(Undo操作) 6. ...

  9. jquery实现文件异步上传

    前言 这里用了2个JS插件,一个是Jquery原生js,我的版本是jquery-1.7.2.min.js,另一个是jquery.form.js.这个form.js 是关键,不可少哦.另外, 我的服务器 ...

  10. 慢牛系列四:好玩的React Native

    在上次随笔(系列三)中,我试着用RN实现了一个Demo,感觉很不错,当时遇到的问题这篇文章里基本都解决了,比如导航动画问题,这篇文章里主要介绍RN的动画,学会动画以后,各种小创意都可以实现了^^ 下面 ...