[KVC翻译]2.6-Key-Value Coding Programming Guide 官方文档第二部分第6节

Key-Value Coding Programming Guide 官方文档第二部分第6节
2018.9.20 第一次修正

iOS-KVC官方文档第二部分第6节

Key-Value Coding Fundamatals--Accessor Search Patterns

访问器搜索方式

NSObject默认实现NSKeyValueCoding协议提供的基于键的访问器,使用一组明确定义的规则来调用对象的基础属性。这些协议方法使用键参数在其自己的对象实例中搜索访问器,实例变量以及遵循某些命名约定的相关方法。尽管您很少修改此默认搜索, 但了解它的工作方式会有所帮助,对于跟踪键值编码对象的行为,也可以使您自己的对象兼容。

注意
本节中的描述使用<key><Key>作为键字符串的占位符,该键字符串在一个键值编码协议方法中作为参数出现,然后该方法将该键字符串用作间接方法调用或变量名称查找的一部分。映射的属性名称遵循占位符大小写的情况。例如,对于getter<key>is<KEY >,名为 hidden 的属性映射为hiddenisHidden .。

基本的Getter搜索模式

valueForKey:的默认实现,给定一个key参数作为输入,在接收valueForKey:调用的类实例中操作,执行以下过程。

1.搜索实例与名称,按照该顺序,搜索找到的名称为get<Key><key>is<Key><key>的第一个访问器方法。如果找到,调用它并继续到步骤5。否则请继续执行下一步。

2.如果找不到简单取值方法, 则在实例中搜索其方法名形如 countOf<Key>objectIn<Key>AtIndex: (相当于NSArray类中定义的基本方法)和<key>AtIndexes:(相当于NSArray类中的objectsAtIndexes:方法)的方法。

如果第一个方法和后边两个方法中的至少一个方法被实现了, 则创建一个能够响应所有NSArray方法并返回该方法的集合代理对象。否则, 继续执行步骤3。

代理对象随后将它接收的任何NSArray消息转换为countOf <Key>objectIn <Key> AtIndex:<key> AtIndexes:的消息,并将其发送给创建它的键值编码兼容对象。如果原始对象还实现了一个名为get <Key>:range:的可选方法,则代理对象也会在适当时使用该方法。实际上,与符合键值编码的对象一起工作的代理对象允许底层属性的行为就像它是一样NSArray,即使它不是。

3.如果没有找到简单的访问器方法或数组访问方法组,请查找名为countOf <Key>enumeratorOf <Key>memberOf <Key>:的方法的三个方法(对应于NSSet类定义的原始方法)。

如果找到所有三个方法,请创建一个响应所有NSSet方法并返回该方法的集合代理对象。 否则,请继续执行步骤4。

这个代理对象随后将它接收的任何NSSet消息转换为count Of <Key>enumeration of <Key>member Of <Key>:消息到创建它的对象。实际上,与符合键值编码的对象一起工作的代理对象允许底层属性的行为就像它是一样NSSet,即使它不是。

4.如果找不到简单访问器方法或集合访问方法组, 并且消息接收者的类方法accessInstanceVariablesDirectly返回YES, 则系统按以下顺序搜索名为:_<key>_is<Key><key>is<Key>的实例变量。如果找到, 则直接获取实例变量的值, 然后继续执行步骤5。否则, 继续跳转到步骤6。

5.如果获取到的属性值是对象指针,即获取的是对象, 则直接将对象返回。

如果获取到的属性值是NSNumber支持的数据类型, 则将其存储在NSNumber实例并返回。
如果获取到的属性值不是 NSNumber 支持的类型, 则转换为NSValue对象, 然后返回。

6.如果上述所有方法都没有执行,则调用valueForUndefinedKey:。 默认情况下,这会引发异常,但NSObject的子类可以通过重载并根据特定key做一些特殊处理。


基本的Setter搜索方式

setValue:forKey:的默认实现, 给定keyvalue参数作为输入, 在接收调用的对象内尝试将名为key的属性设置为value(或者, 对于非对象属性, 则为unwarp value, 详见Representing Non-Object Values), 使用以下过程:

  • 1.按照顺序查找第一个名为set<Key>:_set<Key>的方法。如果找到, 传入输入值 (或根据需要展开值) 调用它, 然后完成。

  • 2.如果找不到简单访问器, 并且类方法accessInstanceVariablesDirectly返回YES, 则按以下顺序查找实例变量: _<key>_is<Key><key>is<Key> 。如果找到, 则直接使用输入值 (或展开值) 设置变量并完成。

  • 3.如果找不到以上方法或实例变量, 则调用setValue:forUndefinedKey:。默认情况下,这会引发异常,但NSObject的子类可以通过重载并根据特定key做一些特殊处理。


可变数组的搜索方式

mutableArrayValueForKey:的默认实现,给定一个key参数作为输入,使用以下过程为接收访问者调用的对象内的一个名为key的属性返回一个可变代理数组:

1.查找一对方法, 名为insertObject:in <Key> AtIndex:removeObjectFrom <Key> AtIndex:的方法(分别对应于NSMutableArray原始方法insertObject:atIndex:removeObjectAtIndex:) ,或者名称类似于insert <Key>:atIndexes:remove <Key> AtIndexes:(对应于NSMutableArrayinsertObjects:atIndexes:removeObjectsAtIndexes:方法)。

如果对象至少实现一个插入方法和至少一个删除方法,则返回一个响应NSMutableArray消息的代理对象,方法是发送insertObject:in <Key> AtIndex:removeObjectFrom <Key> AtIndex:insert <Key>:atIndexes:,和remove <Key> AtIndexes:消息到mutableArrayValueForKey:的原始接收者。

当接收mutableArrayValueForKey:消息的对象也实现了一个可选的替换对象方法,其名称如replaceObjectIn <Key> AtIndex:withObject:replace <Key> AtIndexes:with <Key>:,代理对象在适合最佳性能时会自动调用该可选方法。

2.如果对象没有可变数组方法,则查找名称与模式set <Key>:匹配的访问器方法。 在这种情况下,通过向mutableArrayValueForKey:的原始接收者发出set <Key>:消息,返回响应NSMutableArray消息的代理对象。

注意:
此步骤中描述的机制比上一步的效率要低得多, 因为它可能涉及重复创建新的集合对象, 而不是修改现有的。因此, 在设计自己的键值编码兼容对象时, 通常应避免这种情况。

3.如果既没有找到可变数组方法,也没有找到访问器,并且接收者的类对accessInstanceVariablesDirectly响应'YES,则按照顺序搜索名为_ <key><key>`的实例变量。

如果找到这样的实例变量,则返回一个代理对象,该对象将它接收的每个NSMutableArray消息转发给实例变量的值,该值通常是NSMutableArray的实例或其子类之一。

4.如果所有其他方法都失败了,只要收到NSMutableArray消息,就返回一个可变集合代理对象,该对象向mutableArrayValueForKey:消息的原始接收者发出setValue:forUndefinedKey:消息。

setValue:forUndefinedKey:的默认实现会抛出NSUndefinedKeyException异常, 但子类可能会重写此行为。


可变有序集的搜索方式

mutableOrderedSetValueForKey的默认实现:将相同的简单访问器方法和有序集访问器方法识别为valueForKey :(请参阅 Default Search Pattern for the Basic Getter
),并遵循相同的直接访问实例变量策略,但始终返回可变集合代理对象 valueForKey:返回的不可变集合。 此外,它还执行以下操作:

1.搜索名称类似于以下形式的方法: insertObject:in <Key> AtIndex:removeObjectFrom <Key> AtIndex:(对应于NSMutableOrderedSet类定义的两个最原始方法),以及insert <Key>: atIndexes:remove <Key> AtIndexes:(对应于insertObjects:atIndexes:removeObjectsAtIndexes:)。

如果找到至少一个insert方法和至少一个remove方法,返回的代理对象每次接收到 NSMutableOrderedSet的消息后, 会通过以下组合方法给mutableOrderedSetValueForKey的原始对象 发送消息: mutableOrderedSetValueForKey: insertObject:in<Key>AtIndex:, removeObjectFrom <Key> AtIndex :, insert <Key>:atIndexes: remove<Key>AtIndexes:

代理对象还使用方法名为 replaceObjectIn <Key> AtIndex:withObject: 的方法,或replace<Key>AtIndexes:with<Key>: ,当这些方法存在于原始对象中时。

2.如果找不到可变的set方法,请搜索名为set <Key>:的访问器方法。 在这种情况下,返回的代理对象每次收到NSMutableOrderedSet消息时都会向mutableOrderedSetValueForKey:的原始接收者发送一个set <Key>:消息。

注意
此步骤中描述的机制比前一步骤的效率低得多,因为它可能涉及重复创建新的集合对象而不是修改现有的集合对象。 因此,在设计自己的符合键值编码的对象时,通常应该避免使用它。

3.如果找不到可变集消息和访问器,并且接收者的accessInstanceVariablesDirectly类方法返回YES,则按顺序搜索名称如_ <key><key>的实例变量。 如果找到这样的实例变量,则返回的代理对象将它接收的任何NSMutableOrderedSet消息转发给实例变量的值,该值通常是NSMutableOrderedSet或其子类之一的实例。

4.如果所有其他方法都失败了,那么只要收到一个可变的set消息,返回的代理对象就会向mutableOrderedSetValueForKey:的原始接收者发送一个setValue:forUndefinedKey:消息。

setValue:forUndefinedKey:的默认实现引发了一个NSUndefinedKeyException,但是对象可能会覆盖此行为。


可变集的搜索方式

mutableSetValueForKey:的默认实现,给定一个key参数作为输入,使用以下过程为接收访问者调用的对象内的一个名为key的数组属性返回一个可变代理集:

1.搜索方法名称为add<Key>Object:remove <Key> Object 的方法:(分别对应于NSMutableSet原始方法addObject:removeObject:)以及add<Key>:remove<Key>:(对应于NSMutableSet 方法unionSet:minusSet: )。如果找到至少一个添加方法和至少一个删除方法,则返回一个NSMutableSet代理对象,该代理对象发送add <Key> Object:remove <Key> Object:add <Key>:的某种组合, 和remove <Key>:对于它收到的每个NSMutableSet消息的mutableSetValueForKey:的原始接收者的消息。

代理对象还使用名称为“cross<Key>:”或“set<Key>:”的方法来提高性能(如果可用的话)。

2.如果mutableSetValueForKey:调用的接收者是托管对象,则搜索模式不会像非托管对象那样继续。 有关更多信息,请参阅“Core Data Programming Guide
”中的托管对象访问器方法。

3.如果找不到可变集合方法,并且对象不是托管对象,则搜索名为set <Key>:的访问器方法。 如果找到这样的方法,则返回的代理对象将set <Key>:消息发送给它接收的每个NSMutableSet消息的mutableSetValueForKey:的原始接收者。

注意
此步骤中描述的机制的效率远低于第一步的机制,因为它可能涉及重复创建新的集合对象而不是修改现有的集合对象。 因此,在设计自己的符合键值编码的对象时,通常应该避免使用它。

4.如果找不到可变的set方法和accessor方法,并且accessInstanceVariablesDirectly类方法返回YES,则按照顺序搜索名为_ <key><key>的实例变量。 如果找到这样的实例变量,则代理对象将它接收的每个NSMutableSet消息转发给实例变量的值,该值通常是NSMutableSet的实例或其子类之一。

5.如果所有其他方法都失败了,返回的代理对象通过向mutableSetValueForKey:'的原始接收者发送setValue:forUndefinedKey:消息来响应它收到的任何NSMutableSet`消息。

由于笔者水平有限,文中如果有错误的地方,或者有更好的方法,还望大神指出。
附上本文的所有 demo 下载链接,【GitHub】
如果你看完后觉得对你有所帮助,还望在 GitHub 上点个 star。赠人玫瑰,手有余香。

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

推荐阅读更多精彩内容

  • 开始 关于键值编码 键值编码是一种机制,通过NSKeyValueCoding非正式协议,对象采用这种机制提供对其属...
    影痕残碎阅读 1,167评论 0 2
  • 关于键值编码 键值编码(KVC)是一种由NSKeyValueCoding非正式协议提供的机制,对象采用该机制来提供...
    渐z阅读 892评论 0 0
  • 源码加翻译 #import <Foundation/NSArray.h> #import <Foundation/...
    CAICAI0阅读 1,141评论 0 50
  • 1、介绍: KVC键值编码在iOS中允许开发者通过 Key 直接访问对象的属性,或者给对象的属性或者成员变量赋值,...
    寻形觅影阅读 685评论 0 5
  • 陈浩迷糊睁开双眼,伸了个懒腰,在床上坐起身来,屋内有些暗;看来天色不早了。 “小甜姐不会还没回来吧?” 要是有回来...
    方糖镜阅读 651评论 0 1