KVO解析(四) —— Faults and KVO Notifications

版本记录

版本号 时间
V1.0 2017.09.14

前言

KVO具有更强大的功能,是苹果给我们的一个回调机制,在某个对象注册监听者后,在被监听的对象发生改变时,对象会发送一个通知给监听者,以便监听者执行回调操作。接下来几篇就详细的解析一下KVO。感兴趣的可以看上面几篇。
1. KVO解析(一) —— 基本了解
2. KVO解析(二) —— 一个简单的KVO实现
3. KVO解析(三) —— KVO合规性

Faulting and Uniquing

故障通过在持久存储中保留占位符对象(故障)来减少应用程序的内存使用。 一个名为uniquing的相关功能可以确保在给定的托管对象上下文中,您不会有多个托管对象来表示给定的记录。

faultinguniquing是理解CoreData的两个比较关键的概念。

  • faulting 是一种CoreData降低内存使用的机制,是惰性加载的一种。
  • Uniquing是辅助faulting的机制,它保证了在一个managed object context中只有一个managed object来表达一条记录。

Faulting Limits the Size of the Object Graph - 故障限制对象图的大小

管理对象通常表示持久存储中保存的数据。 在某些情况下,被管理对象可能是一个故障 - 其属性值尚未从外部数据存储加载的对象。 故障可减少应用程序消耗的内存量。 故障是表示尚未完全实现的管理对象的占位符对象或表示关系的集合对象:

  • 管理对象故障是适当类的实例,但其持久变量尚未初始化。
  • 关系故障是代表关系的集合类的子类。

故障允许Core Data在对象图上放置边界。 由于没有实现故障,管理对象故障消耗的内存较少,与故障相关的管理对象根本不需要在内存中进行表示。

为了说明,考虑允许用户获取和编辑有关单个员工的详细信息的应用程序。 员工与经理和部门有关系,这些对象又有其他关系。 如果您从永久存储中检索一个Employee对象,则其经理,部门和报表关系最初由故障表示。 下图显示了以故障为代表的员工部门关系。

A department represented by a fault

虽然这个错误是Department类的一个实例,但它还没有被实现 - 它的持久实例变量都没有设置。 这意味着,不仅部门对象本身消耗的内存较少,也不需要填充其员工关系。 如果要求对象图完成,则要编辑单个员工的单个属性,最终将需要创建对象以表示整个公司结构。


Firing Faults - 故障开启

故障处理是透明的 - 您不必执行抓取来实现故障。 如果在某个阶段访问了故障对象的持久属性,Core Data将自动检索对象的数据并初始化对象。 这个过程通常被称为触发故障。 如果您访问Department对象(例如,其名称)上的属性,则会发生故障触发,Core Data将执行撷取以检索所有对象的所有属性。(有关触发故障开启可以参考NSManagedObject)。

当访问故障的持久属性(如firstName)时,Core Data将自动触发故障。 然而,单独触发故障可能是低效的,并且有更好的策略从永久存储器获取数据(请参阅 Decreasing Fault Overhead)。 要有效地处理故障和关系,请参阅 Fetching Managed ObjectsPreventing a Fault from Firing

当故障触发时,如果数据在缓存中可用,则Core Data不会返回到存储。 使用缓存命中,将故障转换为实现的管理对象非常快 - 它与被管对象的正常实例基本相同。 如果数据在缓存中不可用,则Core Data将自动执行故障对象的提取; 这导致到持久存储器的往返行程以获取数据,并且再次将数据高速缓存在存储器中。

一个对象是否是一个故障,只是指一个给定的被管理对象是否具有所有的持久属性,并且可以使用。 如果需要确定对象是否为故障,请调用其isFault方法而不触发故障(不访问任何关系或属性)。 如果isFault返回NO,则数据必须在内存中,因此对象不是故障。 但是,如果isFault返回YES,则并不意味着数据不在内存中。 数据可能在内存中,或者可能不是,这取决于影响缓存的许多因素。

虽然标准description方法不会导致故障触发,但如果实现访问对象的持久属性的自定义description方法,则故障将触发。 你们绝对不鼓励用这种方式重写description

无法根据需要加载托管对象的各个属性,并避免实现(检索整个对象的所有属性值)。 对于处理大型属性的模式,请参阅 Binary Large Data Objects (BLOBs)


Turning Objects into Faults - 对象转换为故障

将实现的对象转换为故障在修剪对象图中以及确保属性值为最新时可能很有用。 将受管对象转换为故障会释放不必要的内存,并将其内存中的属性值设置为nil。 (请参阅Reducing Memory Overhead并确保数据更新。)

您可以使用 refreshObject:mergeChanges:方法将实现的对象转换为故障。 如果您将NO作为mergeChanges参数传递,则必须确保该对象的关系没有更改。 如果有,然后保存上下文,您将引入持久存储参照完整性问题。

当对象变成故障时,将调用其didTurnIntoFault方法。 您可以实施自定义的didTurnIntoFault方法来执行各种管理功能。

还需要注意的是:Core Data避免了这个unfaulting术语,因为它是混乱的。 虚拟内存页错误没有unfaulting。 页面错误被触发,引起,开启或遇到。 当然,您可以通过各种方式将内存释放回内核(使用函数vm_deallocatemunmapsbrk)。 Core Data将其描述为“turning an object into a fault”。


Faults and KVO Notifications - 故障和KVO通知

当Core Data将对象变成故障时,键值观察(KVO)更改通知将发送到对象的属性。 如果您正在观察变成故障的对象的属性,并且随后实现了故障,你接收的更改通知的属性值实际上并没有实际上的改变。

虽然这些值从您的角度来看不会从语义上改变,但是随着对象的实现,内存中的字面字节也在改变。 键值观察机制要求Core Data在根据指针比较的角度改变值时发出通知。 KVO需要这些通知来跟踪关键路径和依赖对象的变化。


Uniquing Ensures a Single Managed Object per Record per Context - Uniquing确定每个上下文记录的单个管理对象

Core Data可确保在给定的托管对象上下文中 - persistent store中的条目仅与一个管理对象相关联。 该技术被称为uniquing。 没有uniquing,你可能会得到一个上下文来维护多个对象来表示给定的记录。

例如,考虑下图所示的情况,两名员工已被提取到一个单一managed object context.中。 每个人都与一个部门有关系,但该部门目前由一个故障表示。

Independent faults for a department object

看来每个员工都有一个单独的部门,如果您为每个员工调用部门 - 将部门故障转换为常规对象,则内存中将有两个单独的部门对象。 但是,如果两个员工都属于同一部门(例如Marketing),则Core Data可确保(在给定的托管对象上下文中)仅创建了一个代表市场部门的对象。 如果两个员工都属于同一个部门,则他们的部门关系因此都会引用相同的故障,如下图所示。

Uniqued fault for two employees working in the same department

没有uniquing,如果您获取所有员工,并在每个部门中调用部门,从而触发相应的故障 - 每次都会创建一个新的部门对象。 这将导致一些对象,每个对象代表同一个部门,可能包含不同和冲突的数据。 当保存上下文时,将无法确定正确的数据以提交存储。

更广泛地说,在给定上下文中,引用市场部门对象的所有托管对象都引用了相同的实例,即它们具有市场营销部门数据的单一视图,即使市场部门对象是故障的。

这个讨论集中在单一的管理对象上下文中。 每个受管对象上下文都表示数据的不同视图。 如果相同的员工被提取到第二个上下文中,那么它们和相应的Department对象都由内存中的不同对象表示。 不同上下文中的对象可能具有不同的和冲突的数据。 Core Data架构正是检测和解决这些冲突的很好的角色。

后记

这里很大一部分是关于Core Data的,只有一个小点与KVO相关,但是苹果文档写在一起,我就都发出来了,大家感兴趣的也可以看看Core Data方面的知识。未完,待续~~~

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

推荐阅读更多精彩内容

  • 1.Difference between shallow copy and deep copy? 浅复制和深复制的...
    用心在飞阅读 987评论 0 9
  • 1.Difference between shallow copy and deep copy?浅复制和深复制的区...
    小枫123阅读 344评论 1 0
  • 上海 晴 上午参加浦东图书馆的“问道教育”,邀请的是华二和建平的四校八校的校长。 华二娄校长发言: 一开场就谈到马...
    桃子时空阅读 1,101评论 0 0
  • 一、关于谈话 今天谈话的学生是本轮谈话的最后六位学生:田光正、李飞、钱琪琦、苏甜甜、黄群尧和张炎创。作为班级中暂时...
    殷德静阅读 575评论 0 1
  • 朋友在聊天时向我诉苦,说家里的女人总说和他一点默契都没有,许多事情都不喜欢直说非要让他猜来猜去。女人经常为了一点小...
    钱不如意阅读 238评论 0 0