KVC/KVO详解

1.KVC简介

全称是key - value - observing,翻译为键编码。他提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制。

KVC相关技术

KVC定义了一种按名称访问对象属性的机制,其主要方法为:

- (id)valueForKey:(NSString *)key;  
- (void)setValue:(id)value forKey:(NSString *)key;  
- (id)valueForKeyPath:(NSString *)keyPath;  
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;  

KVC和集合运算符

集合运算符是一个特殊的key Path,可以作为参数传递给valueForKeyPath:方法,也只能是这个方法。

  • 简单运算符
    简单集合运算符共有@avg,@count,@max,@min,@sum5种。
    例如:
    有一个集合类的对象:transactions,它存储了一个个的Transaction类的实例,该类有三个属性:payee,amount,date。
    要获取amount的平均值可以这样:
NSNumber *transactionAverage = [transactions valueForKeyPath:@"@avg.amount"];  

要获取transactions集合中元素数目可以这样:

NSNumber *numberOfTransactions = [transactions valueForKeyPath:@"@count"];
  • 对象运算符
    比集合运算符稍微复杂,能以数组的方式返回指定的内容,一共有两种:
@distinctUnionOfObjects  
@unionOfObjects  

它们的返回值都是NSArray,区别是前者返回的元素都是唯一的,是去重以后的结果;后者返回的元素是全集。用法如下:

NSArray *payees = [transactions valueForKeyPath:@"@distinctUnionOfObjects.payee"];  
NSArray *payees = [transactions valueForKeyPath:@"@unionOfObjects.payee"];  

KVC实现原理

KVC再某种程度上提供了访问器的替代方案。不过访问器方法是一个很好的东西,以至于只要是有可能,KVC也尽量再访问器方法的帮助下工作。为了设置或者返回对象属性,KVC按顺序使用如下技术:

  • 检查是否存在get、set方法
  • 直接访问实例变量
  • 抛出异常 我们根据需要重写他们
valueForUndefinedKey:
setValue:forUndefinedKey:
2.KVO简介

全称是Key-value observing,翻译成键值观察。提供了一种当其它对象属性被修改的时候能通知当前对象的机制。

KVO的优点

当有属性改变,KVO会提供自动的消息通知。这样开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同 一个属性,以及相关的值。

注册,指定被观察者的属性

-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context 
keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)

实现回调方法

 -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。是自动调用的,只要你所监听对象的属性或者实例变量发生变化,就自动调用该函数,执行相应操作

解除注册

- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

你可能感兴趣的:(KVC/KVO详解)