objc中国#4 CoreData 阅读笔记

Core Data 是什么?

Core Data 是一个模型层的技术。Core Data 帮助你建立代表程序状态的模型层。Core Data 也是一种持久化技术,它能将模型对象的状态持久化到磁盘,但它最重要的特点是:Core Data 不仅是一个加载、保存数据的框架,它还能和内存中的数据很好的共事。
对象图管理(object graph management)是 Core Data 最强大的功能之一。
Core Data 是完全独立于任何 UI 层级的框架。它是作为模型层框架被设计出来的。

堆栈

当所有的组件都捆绑到一起的时候,我们把它称作 Core Data 堆栈,这个堆栈有两个主要部分。一部分是关于对象图管理,这正是你需要很好掌握的那一部分,并且知道怎么使用。第二部分是关于持久化,比如,保存你模型对象的状态,然后再恢复模型对象的状态。

在两个部分之间,即堆栈中间,是持久化存储协调器(persistent store coordinator),也被称为中间审查者。它将对象图管理部分和持久化部分捆绑在一起,当它们两者中的任何一部分需要和另一部分交流时,这便需要持久化存储协调器来调节了。


coredata

获取对象

这听起来可能非常不重要,但是在这个时候真正发生了很多事情。如果任何子对象偶然发生在内存中,Core Data 保证会复用那些对象。这是Core Data 独一无二的功能。在 context 内,从不会存在第二个相同的单一对象来代表一个给定的 item。

其次,持久化存储协调器有它自己内部对象值的缓存。如果 context 需要一个指定的对象(比如一个子 item),并且持久化存储协调器在缓存中已经有需要的值,那么,对象(即这个 item)可以不通过 store 而被直接加到 context。这很重要,因为访问 store 就意味着执行 SQL 代码,这比使用内存中存在的值要慢很多。

随着我们遍历 item 的子 item,以及子 item 的子 item,我们慢慢地把整个对象图引用到了 managed object context。而这些对象都在内存中之后,操作对象以及传递关系就会变得非常快,因为我们只是在 managed object context 里操作。我们跟本不需要访问持久化存储协调器。在我们的 Item 对象上访问 title,parent 和 children 是非常快而且高效的。

由于它会影响性能,所以了解数据在这些情况下怎么取出来是非常重要的。在我们特定的情况下,由于我们并没接触到太多的数据,所以这并不算什么,但是一旦你需要处理的数据量较大,你将需要了解在背后发生了什么。

当你遍历一个关系时(比如在我们例子中的 parent 或 children 关系)下面三种情况将有一种会发生:(1)对象已经在 context 中,这种操作基本上是没有任何代价的。(2)对象不在 context 中,但是因为你最近从 store 中取出过对象,所以持久化存储协调器缓存了对象的值。这个操作还算廉价(但是,一些操作会被锁住)。操作耗费最昂贵的情况是(3),当 context 和持久化存储协调器都是第一次访问这个对象,这种情况必须通过 store 从 SQLite 数据库取回。最后一种情况比(1)和(2)需要付出更多代价。

如果你知道你必须从 store 取回对象(比如你已经知道没有这些对象),当你限制一次取回多少个对象时,将会产生很大的不同。在我们的例子中,我们希望一次性取出所有子 items,而不是一个接一个。我们可以通过一个特别的技巧 NSFetchRequest。但是我们要注意,当我们需要做这个操作时,我们只需要执行一次取出请求,因为一次取出请求将会造成(3)发生;这将总是独占 SQLite 数据库的访问。因此,当需要显著提升性能时,检查对象是否已经存在将变得非常有意义。你可以使用-[NSManagedObjectContext objectRegisteredForID:]来检测一个对象是否已经存在。

改变对象的值

当我们插入一个新的 Item 对象时,Core Data 知道需要将这些改变存入 store。那么,当你改变对象的 title 时,也会发生同样的事情。

保存 values 需要协调持久化存储协调器和持久化 store 依次访问 SQLite 数据库。和在内存中操作对象比起来,取出对象和值,访问 store 和数据库是非常耗费资源的。不管你保存了多少更改,一次保存的代价是固定的。并且每个变化都有成本。这是 SQLite 的工作方式。当你做很多更改的时候,需要将更改打包,并批量更改。如果你保存每一次更改,将要付出很高的代价,因为你需要经常做保存操作。如果你很少做保存,那么你将会有一大批更改交给 SQLite 处理。

同样需要注意的是保存操作是原子性的,要么所有的更改会被提交给 store/SQLite 数据库,要么任何更改都不被保存。当实现自定义 NSIncrementalStore 基类时,这一点一定要牢记在心。要么确保保存永远不会失败(比如说不会发生冲突),要么当保存失败时,你 store 的基类需要恢复所有的改变。否则,在内存中的对象图最终和保存在 store 中的对象不一致。

如果你使用一个简单的设置,保存操作通常不会失败。但是 Core Data 允许每个持久化存储协调器有多个 context,所以你可能陷入持久化存储协调器层级的冲突之中。改变是对于每个 context 的,另一个 context 的更改可能导致冲突。Core Data 甚至允许完全不同的堆栈访问磁盘上相同的 SQLite 数据库。这明显也会导致冲突(比如,一个 context 想要更新一个对象的值,而另一个 context 想要删除这个对象)。另一个导致保存失败的原因可能是验证。Core Data 支持复杂的对象验证策略。这是一个高级话题。一个简单的验证规则可能是: Item 的 title 不能超过300个字符。但是 Core Data 也支持通过属性进行复杂的验证策略。

我们需要先进行数据表的设计 —— 设计好的数据模型会以Managed Object Model的形式存在于内存中。采用面向对象的思想进行表的设计时,每一张表描述着一种实体(NSEntityDescription),一份NSManagedObjectModel则包含着多种NSEntityDescription。

一份NSManagedObjectModel,如cdNBA.xcdatamodel,可以包含多份NSEntityDescription,如Player、Team,而每一份NSEntityDescription有三种属性,分别是Attributes、Relationships和Fetched Properties。

根据NSEntityDescription创建出来的对象比较特殊,我们称之为NSManagedObject。由于它的特殊性,当我们要创建一个NSManagedObject对象时,比如Player实例,我们需要为其提供一个生存环境,称之为NSManagedObjectContext。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 卷首语 欢迎来到 objc.io 第四期! 本期我们将深入地研究苹果提供的模型层框架,Core Data。 Cor...
    评评分分阅读 879评论 0 9
  • 转载自Core Data概述 Core Data 可能是 OS X 和 iOS 里面最容易被误解的框架之一,为了帮...
    夏天的风_song阅读 865评论 0 4
  • 本文是对 MagicalRecord github上的翻译 正文:注意: MagicalRecord 在 ARC...
    騂跃神话阅读 1,978评论 1 5
  • 沙盒 Plist Preference偏好设置 NSKeyedArchiver归档 / NSKeyedUnarch...
    追风者366阅读 3,302评论 0 6
  • GTD其实适用人群极为有限,并非适合所有人,甚至对大部分人来说,是一场噩梦。我在很多年以后,才明白这个道理。具体表...
    snipersteve阅读 1,556评论 6 17