iPhone KVO、KVC、KVB介绍 (FWD)

 

先介绍几个关于Runtime System的概念:

  (1) isa指针:当一个对象被创建时,内存布局中的第一个元素是指向类结构的指针,即isa。通过isa指针,一个对象可以访问它的类结构,进而访问继承的类结构。

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

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

KVC、KVO、KVB概念区别

  通过名字看上去,这三种很相似,但是其并不一样,不过其作用也是相辅相成的。这些功能都由系统框架提供支持,使用也很方便。下面简单描述下:

  KVC就是类似使用[myObj setValue:key:]的方式去设置/获取属性值的操作方式

  KVB是用来绑定对象与观察者的

  KVO是观察者模式的一个改进版本,如果通过KVB绑定后,就可以通过KVO来获取对象属性更改的通知。

KVO机制

  KVO(即Key-Value Observe)是cocoa针对观察者模式进行的改进,它提供了可以观察一个对象属性的方法,从而收到相应通知。这有点类似与NSNotification,但是NSNotification需要发送一个NSNotification对象,相比之下,KVO机制则显得更加简单。

KVC实现分析

  KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

    比如说如下的一行KVC的代码:

  [site setValue:@”sitename” forKey:@”name”];

  就会被编译器处理成:

  SEL sel = sel_get_uid (“setValue:forKey:”);

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

  method(site, sel, @”sitename”, @”name”);

 如上,使用KVC在调用setValue:forKey:对象时,大概分成三个步骤:

1. 获取SEL对象

2. 通过sel对象和当前的isa指针,获取函数指针(IMP对象)

3. 通过C函数指针的调用方式,直接调用函数(此处省去了发送消息的开销)

KVB(Key-Value Binding)

绑定,即为对象的观察者与被观察者之间建立联系。
1. 为调用对象添加观察者

– (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

函数说明:

observer-观察者对象

keyPath-对象的key,需要观察的属性

options-观察键值变化的几种可选方式

context-可以传NULL,如果非NULL,则在观察者回调函数中会收到一些数据

2. 观察者收到消息后的处理函数

– (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

函数说明:

keyPath-对象的key,需要观察的属性

object-发送通知的对象

change-包含变化之前与变化之后属性值的字典

context-被观察者对象传入的context

后续会介绍Runtime System,计划在此对KVO/KVC进行一些分析。

可能包括如下:

KVC属性查找逻辑

KVO与观察者

KVO与NSNotification

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s