kvc和kvo

KVO & KVC  

2013-01-13 10:33:17|  分类: 默认分类 |  标签:ios  |举报|字号 订阅

 
 
 
之前偶然看见一大神解释的KVC和KVO,看完都不知到底在说神马,没图没码怎么可能出来真相呢?所以就抽空整理了一下KVC和KVO的一些基本概念,还添加了一些代码,分享给其他人,也给自己留个笔记以后复习。:)
 
1、KVC (Key Value Coding),简单来讲,就是给属性设置值的;复杂来讲,根据网上的说法,KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据

比如说如下的第一行KVC的代码,其实和第二行的普通代码是等效的:

[myClass setValue:@"Andy Yi" forKey:@"name"];

myClass._name = @"Andy Yi";

 

KVC的代码会被编译器处理成:

SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (myClass->isa,sel);
method(site, sel, @"Andy Yi", @"name");

这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候:

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

b.  它会从自己isa指针结合环境参数,找到具体的方法实现的接口。

c.  再直接查找得来的具体的方法实现。

2、KVO提供了观察某一属性变化的方法,实现了两个对象之间的交互。这种观察-被观察模型特别适用于MVC这种架构的程序,比方说根据业务层面的某个属性值变化,则UI层的某个属性做出相应变化。熟悉KVO的朋友都知道,只有当我们调用KVC去访问key值的时候KVO才会起作用。所以肯定确定的是,KVO是基于KVC实现的。使用KVO一般需要做如下的几步:

 

a.  注册:

 

[myClass addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];

 

myClass是被观察的对象;Observer是观察者的对象;keyPath就是要观察的属性值;options给你观察键值变化的选择;而context方便传输你需要的数据

 

b.  实现变化方法。此处注意,如果一个ViewController同时观察了多个对象,那么在这里一定要判断一下这个keypath是不是你需要处理的那个对象,如果需要的话,最好再用“isMemberOfClass”判断一下你的对象的类型是否正确,否则容易出错,友情提醒一下。


-(void) observeValueForKeyPath:(NSString *)keyPath

                      ofObject:(id)object

                        change:(NSDictionary *)change

                       context:(void *)context {

    

    if ([keyPath isEqualToString:@"_name"] && [object isMemberOfClass:[MyClass class]]) {

        

        nameLabel.text = myClass.name;

    }

    

}

 
 
在iOS中,我们使用KVO最主要的目的还是实现两个对象之间的交互,主要做的好处显而易见,打个比方,比如你在代码的很多地方都需要根据属性的变化来更新UI,如果没有KVO那么,比较本能的一个方法就是你需要在每个更新属性的时候加上UI更新的代码,因为有了KVO,你只需要添加一处UI更新的代码,因为KVO代码会自动的跟踪属性的变化,当变化的时候,会自己调用同一个变化的方法来处理,这就是一个明显的好处,减少代码的冗余,其实也可以从另外的一个层面来讲,就是分层比较明确。还有一个问题,那就是实现两个对象之间的交互,那Notification也可以,那两者之间的差别在哪里,其实这个问题还是比较容易理解的,最大的区别在于Notification不是严格意义上的两个对象的交互,其实中间有一个NotificationCenter来作为中间人来进行沟通,KVO就纯粹是连个对象之间的交互了,两者的相同点是都需要在最后释放注册的Object。
原文地址:https://www.cnblogs.com/wangzh1225/p/3528588.html