认识CoreData - 初识CoreData

该文章属于<简书 — 刘小壮>原创,转载请注明:

<简书 — 刘小壮> http://www.jianshu.com/p/c0e12a897971git


这段时间公司一直比较忙,和组里小伙伴一块儿把公司项目按照以前逻辑重写了一下。因为项目比较大,还要兼顾以前项目的迭代和其余项目,目前为止只写完第一阶段。 以前项目本地持久化方案主要用的是SQLite,此次重写项目打算换一种持久化方案,因而咱们通过讨论选择了苹果的“亲儿子”CoreData。 在使用CoreData的过程当中,我也是一边学习一边实践。在学习的过程当中,一些写的质量比较高的博客对个人帮助也很大,例如objc.io等博客,在这里就不一一列举出来了,很是感谢这些做者。程序员

先不说项目中用不用获得,其实不少人都是不了解CoreData的,可是通过个人学习发现CoreData仍是挺不错的。因此正如这系列文章的名字同样-认识CoreData,打算写这系列文章来认识一下CoreData。 这系列博客将从简单到复杂的来说一下CoreData,其中除了基础使用还会包括多线程、批量数据处理等内容,这些不少都是我公司项目开发过程当中接触到的,咱们也设想了一些极端的状况,解决方案都会体如今这系列博客中。github

本人接触CoreData时间并不长,只是专门花了一段时间学习CoreData。 本系列文章偏重于经过图形化界面使用CoreData,不会所有采起纯代码进行CoreData的全部操做,并且那样操做起来也确实比较麻烦,反而就失去了CoreData的优点和本质。sql

文章中若有疏漏或错误,还请各位及时提出,谢谢!数据库


占位图

写在前面

CoreData中有一些经常使用的类,称呼可能各不相同。因此这里先约定一些关键字,以便理解后面的一些内容,这些约定不少都是出如今苹果的官方文档中的。 NSPersistentStoreCoordinator(Persistent Store Coordinator),缩写为PSCNSManagedObjectContext(Managed Object Context),缩写为MOCNSManagedObjectModel(Managed Object Model),缩写为MOMNSManagedObject及其子类,根据英文翻译和其做用,称之为托管对象。 后缀名为.xcdatamodeld的文件,由于存储着全部实体的数据结构和表示,因此称之为模型文件缓存

什么是CoreData?

简单介绍一下

CoreData出如今iOS3中,是苹果推出的一个数据存储框架。CoreData提供了一种对象关系映射(ORM)的存储关系,相似于Javahibernate框架。CoreData能够将OC对象存储到数据库中,也能够将数据库中的数据转化为OC对象,在这个过程当中不须要手动编写任何SQL语句,这是系统帮咱们完成。安全

CoreData最大的优点就是使用过程当中不须要编写任何SQL语句,CoreData封装了数据库的操做过程,以及数据库中数据和OC对象的转换过程。因此在使用CoreData的过程当中,不少操做就像是对数据库进行操做同样,也有过滤条件、排序等操做。服务器

这就至关于CoreData完成了Model层的大量工做,例如Model层的表示和持久化,有效的减小了开发的工做量,使Model层的设计更加面向对象。数据结构

CoreData好用吗?

以前听人说过,CoreData比较容易入手,可是很难学精。这也是不少人说CoreData很差用的缘由之一,只是由于使用方式有问题,或者说并无真正掌握CoreData多线程

若是从性能上来讲,CoreDataSQLite确实略差一些。可是对于移动端来讲,并不须要大型网站的高并发,因此这点性能差异几乎是没有影响的,因此这点能够忽略不计。在后面的文章中,将会给出CoreData的优势和缺点对比,以及详细的性能测评。

CoreData主要的几个类
  • NSManagedObjectContext 托管对象上下文,进行数据操做时大多都是和这个类打交道。
  • NSManagedObjectModel 托管对象模型,一个托管对象模型关联一个模型文件(.xcdatamodeld),存储着数据库的数据结构。
  • NSPersistentStoreCoordinator 持久化存储协调器,负责协调存储区和上下文之间的关系。
  • NSManagedObject 托管对象类,全部CoreData中的托管对象都必须继承自当前类,根据实体建立托管对象类文件。
CoreData简单建立流程
  1. 模型文件操做 1.1 建立模型文件,后缀名为.xcdatamodeld。建立模型文件以后,能够在其内部进行添加实体等操做(用于表示数据库文件的数据结构) 1.2 添加实体(表示数据库文件中的表结构),添加实体后须要经过实体,来建立托管对象类文件。 1.3 添加属性并设置类型,能够在属性的右侧面板中设置默认值等选项。(每种数据类型设置选项是不一样的) 1.4 建立获取请求模板、设置配置模板等。 1.5 根据指定实体,建立托管对象类文件(基于NSManagedObject的类文件)

  2. 实例化上下文对象 2.1 建立托管对象上下文(NSManagedObjectContext) 2.2 建立托管对象模型(NSManagedObjectModel) 2.3 根据托管对象模型,建立持久化存储协调器(NSPersistentStoreCoordinator) 2.4 关联并建立本地数据库文件,并返回持久化存储对象(NSPersistentStore) 2.5 将持久化存储协调器赋值给托管对象上下文,完成基本建立。

CoreData结构

CoreData的结构构成

以前看到过几张介绍CoreData结构的图片,感受其表示的结构比较清晰。能够经过这几张图片初步认识一下CoreData,在后面的文章中还会对这几个类进行详细解释。

总体结构

上图中是初始化MOC所涉及到的一些类,由这些类实例化并最终构成可使用的MOC。图中编号是实例化一个具有数据处理能力的MOC过程,这个过程和上面介绍过的实例化上下文对象相同。

NSManagedObjectContext

PSC建立并关联本地数据库,并设置为MOCpersistentStoreCoordinator属性后,MOC就具有对当前存储区全部托管对象操做的能力。可是须要注意的是,MOC对托管对象是懒加载的,在使用时才会被加载到MOC的缓存中。

NSManagedObjectModel

MOM对象加载模型文件后,获取到模型文件中全部实体的构成结构。因为MOM中存储着模型文件的结构,PSC须要经过MOM对象实例化本地数据库。

Entity

全部属性都存在Entity中,以及有关联关系的属性和请求模板,这都会在后面的章节中讲到。

NSManagedObject

能够经过Entity建立继承自NSManagedObject类的文件,这个文件就是开发中使用的托管对象,具有模型对象的表示功能,CoreData的本地持久化都是经过这个类及其子类完成的。

持久化存储调度器

CoreData的总体结构中,主要分为两部分。一个是NSManagedObjectContext管理的模型部分,管理着全部CoreData的托管对象。一个是SQLite实现的本地持久化部分,负责和SQL数据库进行数据交互,主要由NSPersistentStore类操做。这就构成了CoreData的大致结构。

结构图

从图中能够看出,这两部分都是比较独立的,两部分的交互由一个持久化存储调度器(NSPersistentStoreCoordinator)来控制。上层NSManagedObjectContext存储的数据都是交给持久化调度器,由调度器调用具体的持久化存储对象(NSPersistentStore)来操做对应的数据库文件,NSPersistentStore负责存储的实现细节。这样就很好的将两部分实现了分离。

我的随想

对于CoreData的总体结构,由于CoreData底层存储原本就是用SQLite实现的,因此我用CoreData的结构和SQLite对比了一下,发现仍是不少类似之处的。

.xcdatamodeld文件表明着数据库文件结构,经过.xcdatamodeld编译后的.momd文件生成数据库。每一个实体表明一张数据表,实体之间的关联关系就是SQLite的外键。

下图就是CoreData底层存储的结构,用红圈圈住的部分指向关联表的主键下标。例如1就指向关联表的主键下标为1的行。

外键

CoreData杂谈

CoreData数据存储安全

CoreData本质仍是使用SQLite进行存储,并无另外提供加密功能,具体的数据加解密还须要本身完成。

CoreData在硬盘上的数据存储结构

数据库存储结构

经过PSC指定建立SQLite目录后,会在指定的目录下生成一个数据库文件,同时还会生成两个同名但后缀不一样的文件,其中只有后缀.sqlite的文件是存储数据的文件。

这个数据库文件中会默认生成三个表,Z_METADATAZ_PRIMARYKEYZ_MODELCACHE,其余咱们本身的表也都是大写Z开头的。

在每一个表中,系统还会默认生成三个字段,Z_PKZ_ENTZ_OPT三个字段,也都是大写Z开头而且带下划线的。其余字段就是咱们本身的字段了,大写Z开头但不带下划线。

CoreData执行效率

如今市面上的大多数项目,都是使用SQLite做为持久化的方案,而CoreData的使用并非很广泛。对于这个问题,我认为首先是不少项目开始的比较早,那时候好多iOS程序员都是从其余语言转过来的,更加熟悉SQLite,因此用SQLite比较多一些。后面若是不进行大的项目重构,就很难换其余的持久化方案了。

还有就是不熟悉CoreData,也不想去了解和深刻学习CoreData,我认为这是很大的缘由。因此项目中用CoreData的人并很少,而真正掌握CoreData技术的人更少。

以前听其余人说CoreData的执行效率不如SQLite高,这个若是深究的话,确实CoreData要比SQLite效率差一些,只不过并无太大区别。CoreData本质也是在底层执行SQL语句,只是CoreDataSQL语句执行逻辑比较耗时,没有手动编写SQL语句更加直接。咱们能够将CoreData的调试功能打开,具体看一下SQL语句的执行。

这里要说一点,客户端毕竟不是服务端,不须要像服务器那样大量的数据查询,因此CoreData是彻底能够应对客户端的查询量的。若是从灵活性来讲,CoreData确实没有SQLite的灵活性高,一些SQLite的复杂功能可能也不能实现,可是就目前大多数项目来讲,CoreData已经可以知足项目持久化需求了。

致使执行效率差别的缘由还体如今对象转换上,CoreData在执行SQL语句的基础上,还多了一层将数据映射给托管对象的操做,这样获得的就是OC的托管对象,而SQLite获得的则不是。若是给SQLite执行完成后,也加一层建立托管对象并赋值的操做,这时候对比性能二者的差距可能就会更小了。

性能评测

下面是一篇关于CoreDataFMDBRealm性能测试结果的博客,最后的结果我也没有去验证,只是大体看了一下代码仍是比价靠谱的。做者测试Demo原文地址

** 测试数据的数量是以K为单位,最少为1K的数据量。涉及到的操做主要是下面四种**:

  1. 新建数据库并插入1K条数据。
  2. 已有数据库,插入1K条数据。
  3. 查询总量为10K条数据,连续查询单次为1K数据。
  4. 10K条数据总量,更新其中1K条数据的部分字段性能。
性能评测结果:

根据测试结果能够发现,在前面两种插入操做,CoreData的性能比FMDBRealm要快不少。

而对于查询操做,CoreData比其余两种操做耗时多不少,大概多出三四倍。这极可能和CoreData将查询结果的数据转为托管对象有关系,抛去CoreData这部分转换操做性能会比如今好不少。

而更新操做则直接基于SQLite封装的FMDB有绝对的优点,FMDB和其余两种操做差距大概是十倍左右,而其余两种操做性能差很少。固然CoreData也存在着上面提到的对象转换操做,CoreData抛去这步结果可能会比如今好不少。

测试图表

下面的测试数据中,取得是三次测试结果的平均值。

第三方 编号
CoreData 1
FMDB 2
Realm 3

新建数据库并插入1K条数据

已有数据库,插入1K条数据

查询总量为10K条数据,连续查询单次为1K数据

10K条数据总量,更新其中1K条数据的部分字段性能

CoreData调试

Xcode调试命令

CoreData本质上是对SQLite的一个封装,在内部将对象的持久化转化为SQL语句执行,能够在项目中将CoreData调试打开,从而能够看到CoreDataSQL语句执行和一些其余log信息。

  1. 打开Product,选择Edit Scheme.
  2. 选择Arguments,在下面的ArgumentsPassed On Launch中添加下面两个选项。 (1)-com.apple.CoreData.SQLDebug (2)1
终端调试命令

若是是在模拟器上调试程序,能够经过 sqlite3 /数据库路径/ 命令来查看和操做数据库。 .tables 查看当前数据库文件中全部的表名 select *from tableName 执行查询的SQL语句

终端调试命令


好多同窗都问我有Demo没有,其实文章中贴出的代码组合起来就是个Demo。后来想了想,仍是给本系列文章配了一个简单的Demo,方便你们运行调试,后续会给全部博客的文章都加上Demo

Demo只是来辅助读者更好的理解文章中的内容,应该博客结合Demo一块儿学习,只看Demo仍是不能理解更深层的原理Demo中几乎每一行代码都会有注释,各位能够打断点跟着Demo执行流程走一遍,看看各个阶段变量的值。

Demo地址刘小壮的Github


这两天更新了一下文章,将CoreData系列的六篇文章整合在一块儿,作了一个PDF版的《CoreData Book》,放在我Github上了。PDF上有文章目录,方便阅读。

若是你以为不错,请把PDF帮忙转到其余群里,或者你的朋友,让更多的人了解CoreData,衷心感谢!

相关文章
相关标签/搜索