您的位置:首页 > 产品设计 > UI/UE

[iOS] KVO(NSKeyValueObserving)、KVC(NSKeyValueCoding)作用浅谈

2012-11-09 18:16 981 查看
在很多时候接触到很多地方都有对KVC,KVO的描述,但是都是一笔带过。只知道这是Object-C提供的一个不错的机制,可以很好的减少浇水代码。

  其实KVC、KVO即NSKeyValueCoding和NSKeyValueObserving的简称。

  在官方文档中描述为









  那我们KVO、KVC用来做什么的我们又怎么使用它呢?

  首先我们先了解下KVO的机制

  KVO:当指定的对象的属性被修改了,允许对象接收到通知的机制。每当在类中定义一个监听

  如:

  [self addObserver:self

  forKeyPath:@"items"

  options:0

  context:contexStr];

  ***

  当然你还可以监听其他对象的属性变化

  [person addObserver:money

  forKeyPath:@"account"

  options:0

  context:contexStr];

  ****

  只要当前类中items这个属性发生的变化都会触发到以下的方法。

  - (void)observeValueForKeyPath:(NSString *)keyPath

  ofObject:(id)object

  change:(NSDictionary *)change

  context:(void *)context

  KVO的优点:

  当有属性改变,KVO会提供自动的消息通知。这样开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。

  这是KVO机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。

  开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可以在工程里使用。

  其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同 一个属性,以及相关的值。

  KVC的实现分析

  KVC运用了一个isa-swizzling技术。

  isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。

  isa指针,就是is a kind of的意思,指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

  如下KVC的代码:

  [person setValue:@"personName" forKey:@"name"];

  就会被编译器处理成:

  SEL sel = sel_get_uid ("setValue:forKey:");

  IMP method = objc_msg_lookup (person->isa,sel);

  method(person, sel, @"personName", @"name");

  ***

  其中:

  SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

  IMP数据类型:他其实就是一个 编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型。

  ***

  KVC在调用方法setValue的时候

  (1)首先根据方法名找到运行方法的时候所需要的环境参数。

  (2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。

  (3)再直接查找得来的具体的方法实现。

  这样的话前面介绍的KVO实现就好理解了

  当一个对象注册了一个观察者,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。

  所以isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。

  这样只有当我们调用KVC去访问key值的时候KVO才会起作用。所以肯定确定的是,KVO是基于KVC实现的。

zz from: http://chinaxxren.iteye.com/blog/1150430
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: