//重新整理了下自己原先的博客
kvc与kvo
一、kvc的概述
KVC是KeyValueCoding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性(实例变量)的机制。而不是通过调用Setter、Getter方法访问。
当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。
1>kvc的使用方法
关键方法定义在:NSKeyValueCodingprotocol
KVC支持类对象和内建基本数据类型。
关键方法定义在:NSKeyValueCodingprotocol
KVC支持类对象和内建基本数据类型。
获取值
valueForKey:,传入NSString属性的名字。
valueForKeyPath:,传入NSString属性的路径,xx.xx形式。
valueForUndefinedKey它的默认实现是抛出异常,可以重写这个函数做错误处理。
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUndefinedKey:
setNilValueForKey:当对非类对象属性设置nil时,调用,默认抛出异常。
一对多关系成员的情况
mutableArrayValueForKey:有序一对多关系成员 NSArray
mutableSetValueForKey:无序一对多关系成员 NSSet
例如
Person *p = [Person new];
//使用kvc间接修改对象的属性时,系统会自动判断对象属性的类型,并完成转换
[p setValue:@"jake" forKey:@"name"];
//NSNumber 基本类型的数据
//NSValue 结构体
[p setValue:@"80" forKey:@"age"];
Person *p1 = [Person new];
//使用kvc间接修改对象的属性时,系统会自动判断对象属性的类型,并完成转换
[p1 setValue:@"mike" forKey:@"name"];
//NSNumber 基本类型的数据
//NSValue 结构体
[p1 setValue:@"18" forKey:@"age"];
NSLog(@"p = %@ p 1 =%@",p,p1);
NSArray *person = @[p,p1];
NSLog(@"%@",person);
//只生成name的数组
// NSMutableArray *arrayM = [NSMutableArray array];
//kvc按照键值路径取值,如果对象不包含指定的键值,会自动进入对象的内部,查找对象属性
NSArray *array = [person valueForKey:@"name"];
NSLog(@"%@",array);
使用valueForKey:获取Student对象的name
NSString *name = [student valueForKey:@"name"];
valueForKey:首先查找以name或isName命名的getter方法,如果不存在getter方法,就在对象内部查找名为_name或name的实例变量
注意,下列语句是合法的
NSLog(@"age is %@", [student valueForKey:@"age"]);
NSLog中的%@输出一个对象,但age是一个int值,而不是对象,为什么会合理呢?原因如下:
使用valueForKey:时,KVC会自动将标量值(int、float、struct等)翻入NSNumber或NSValue中包装成一个对象,然后返回。因此,KVC有自动包装功能。
键路径(key path)
除了通过键设置值外,KVC还支持键路径,像文件系统路径一样,其实就是属性链式访问
比如,利用键路径设置Student对象中Card对象的no
[student setValue:@"12345" forKeyPath:@"card.no"];
获取Student对象中Card对象的no
[student valueForKeyPath:@"card.no"];
二、kvo的基本概念
Key-Value Observing (KVO) 建立在 KVC 之上,它能够观察一个对象的 KVC key path 值的变化。举个例子,用代码观察一个 person 对象的 address 变化,以下是实现的三个方法:
1>kvo的使用
watchPersonForChangeOfAddress: 实现观察
observeValueForKeyPath:ofObject:change:context: 在被观察的 key path 的值变化时调用。
dealloc 停止观察
监听器需要实现监听方法
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
keyPath :监听的属性
object :谁的属性改变了
change :属性改变时传递过来的信息(取决于添加监听器时的options参数)
移除监听器
-(void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath
*/
KVC--KVO--KVB优势
些机制通过规定了一组通用的Cocoa命名法则、调用规则等,实现了如下功能:
1. 使用一对高度规范化的访问方法,获取以及设置任何对象的任何属性的值(所谓的属性既可以是个实实在在的成员变量,也可以是通过一对成员方法所抽象出的该对 象的一个性质)。
2. 通过继承一个特定的方法,并且指定希望监视的对象及希望监视的属性名称,就能在该对象的指定属性的值发生改变时,得到一个“通知”(尽管这不是一个真正意 义上的通知),并且得到相关属性的值的变化(原先的值和改变后的新值)。
3. 通过一个简单的函数调用,使一个视图对象的一个指定属性随时随地都和一个控制器对象或模型对象的一个指定属性保持同步。