实现KeyValue Coding 的5种方法

简介

Key-Value Coding(以后都简称为KVC),是一种设计模式,其想法就是不用对对象的某个属性进行设置或者读取,而是使用key来访问。这种模式在Map中是很容易理解的,因为Map/Dictionary中保存的就是key-value 对,对这个pair进行操作,都是通过key来操作的。KVC就不仅仅限于Map/Dictionary,而是把它扩展到了普通对象。任何不同对象的instance variable都可以用KVC。使用KVC的好处就是可以将变量本身与他要关联的属性进行解耦,比如有个值,代表下载进度,进度一方面要在UI的进度条上显示出来,一方面用数字的方式显示在另一个地方(Console,Label on UI),这个值一改变,其关联的地方都要改,传统的方式就是一个一个地该,而基于KVC的方式,将这个值的key跟需要同步的属性关联,依赖KVC提供的互相更新的机制,就可以不用在代码中一个一个的改了。

实现KVC 有多种方式,在引用的文章里介绍了5种,我们分别探究一下其原理。

1. NSKeyValueCoding 协议

NSKeyValueCoding协议是informal的,其中定义了使用最多用于 set 和 get 的两个函数 setValue:forKey: 和 valueForKey:。 Cocoa使用Category on NSObject实现了这些方法,其他方法可以看NSKeyValueCoding协议doc。

优点

  1. 这种方法可以自动找到get/set 方法,即使get/set方法不存在,还可以之间操控ivars。因此大多数property 都自动支持这个功能了。
  2. 包含key的路径()?
  3. 与NSKeyValueObserving 集成,可以很容易实现Observer模式;
  4. 有fallback机制处理undefined key的情况;

缺点

  1. 其扩展的search path使其性能很差;
  2. 需要一个NSKeyValueCoding 能找到的方法或者ivar被定义在类中;

2. Manual subsets of NSKeyValueCoding behavior

NSKeyValueCoding 协议使用selector name找方法的名字,使用那么找ivar的名字。这种方法是可以自己实现的,这样就可以实现定制行为了:比如自己定的search path等。

优点

  1. 比NSKeyValueCoding协议方法相比,对lookup path有更多控制权;
  2. 可能比NSKeyValueCoding 快;??
  3. 对于非NSObject子类也可以用;
  4. 可以实现对对non-object 值的操作;

缺点

  1. 不如NSKeyValueCoding协议flexible;
  2. 大多数情况下,比NSKeyValueCoding协议需要更多work;

3. Associated objects

Objective C运行时允许将任何object与其他任一object关联,这就使得任一object可以拥有额外的一组使用key设置的property 集合。而不需要对象ivars或者方法提供支持。这种方法的适用环境是:从外界设置对象的属性(比如从没有对象的支持、?????)

优点

  1. 不需要对象提供特殊支持;
  2. key可以是任何pointer;
  3. 有潜力是最快的KVC方式;

缺点

  1. key是指针,不是对象,所以如果一个对象被使用时,它必须指向unique的对象;
  2. 不影响对象的ivas和method。也就是说,这个object并不知道KVC的进行,如果你需要这个对象知道这些变化,就需要使用其他方式。

4. selectors as keys

KVC的实现主要就是需找某个key对应的property,然后对这个property执行操作。Objective-C的runtime提供了这种以SEL查找的API:objc_msgSend。这种方式类似于部分实现NSKeyValueCoding 协议。这种方式最好使用SEL作为key。

优点

  1. 对方法遍历的最快方法;
  2. 可以get/set non-object数据(需要使用objc_msgSend_fpret 和 objc_msgSend_stret 等实现);

缺点

get/set需要不同的key

selector不是对象,所以不能在ObjC的array或者Dictionary中存储;

5. Do it by yourself

最后的办法就是自己实现,This is something you would do if you needed maximum flexibility (for handling unusual keys/values) or wanted to expose different key-value sets from a single object.

优点

  1. 一个对象可以暴露多个、独立的collection
  2. 可以get/set 底层collection支持的任何数据类型;
  3. 对fallback和处理特殊情况的最灵活的方法;

缺点

  1. 必须由target class实现;
  2. 不能跟NSKeyValueObserving 和NSKeyValueCoding配合使用;

引用:

1. http://disanji.net/2010/12/12/5-key-value-coding-approaches-in-cocoa-html/

2. http://www.cocoawithlove.com/2010/01/5-key-value-coding-approaches-in-cocoa.html

原文地址:https://www.cnblogs.com/whyandinside/p/2942645.html