KVC,KVO的区别和使用
KVC/KVO的理解
KVC/KVO 这方面知识以前在面试的时候遇到过,平时使用的并不多,但是查了一些博客后觉得这个东西很重要,今后应该多尝试使用到程序中去.
这方面知识我是从一片博客中了解的,自己写了小程序测试了一下.博客地址在这里,感谢博主!
KVC:即Key-Value Coding,是一个非正式的 Protocol,提供一种机制来间接访问对象的属性。KVO 就是基于 KVC 实现的关键技术之一。
一个对象拥有某些属性。比如说,一个 Person 对象有一个 name 和一个 address 属性。以 KVC 说法,Person 对象分别有一个 value 对应他的 name 和 address 的 key。 key 只是一个字符串,它对应的值可以是任意类型的对象。
下面附上代码
@interfacePerson :NSObject
@property(nonatomic,copy)NSString*name;
@property(nonatomic,copy)NSString*age;
@property(nonatomic,copy)NSString*sex;
@property(nonatomic,copy)NSString*addr;
@property(nonatomic,copy)NSString*Test;//如果这里是大写开头,而dict里面是小写开头,则会报错,反之,如果这里是小写,那么dict里面首字母是大小写不影响
@property(nonatomic,retain)Person*per;
@implementationPerson
-(void)setValue:(id)value forUndefinedKey:(NSString*)key//如果dict里面的键值对的key本类中没有定义,写这个函数则会消除报错,本质上是,当使用setValue:forKey来定义本类未定义的值时,使用这个类来消除错误
{
}
#if0
Person *p = [[Person alloc] init];
[p setValue:@"张红"forKey:@"name"];
[p setValue:@"13"forKey:@"age"];
[p setValue:@"东部野马"forKey:@"addr"];
[p setValue:@"Error"forKey:@"error"];
NSDictionary *dict =@{@"name":@"海南",@"age":@"22",@"sex":@"boy",@"addr":@"东南海",@"errors":@"err",@"Test":@"Test"};
Person *p1 = [[Person alloc] init];
[p1 setValuesForKeysWithDictionary:dict];
NSLog(@"name = %@,sex = %@,age = %@,addr = %@,test = %@",[p1 valueForKey:@"name"],[p1 valueForKey:@"sex"],[p1 valueForKey:@"age"],[p1 valueForKey:@"addr"],[p1 valueForKey:@"Test"]);
NSLog(@"%@",[p valueForKey:@"name"]);
Person *per = [[Person alloc] init];
//per = [p valueForKey:@"per"];
per.name =@"testname";
[p setValue:per forKey:@"per"];
//[p setValue:@"namejtest" forKeyPath:@"per.name"];
NSLog(@"test = %@",[p valueForKeyPath:@"per.name"]);
#else
arr= [NSMutableArrayarray];
Person*p2 = [[Personalloc]init];
Person*per = [[Personalloc]init];
[p2setValue:perforKey:@"per"];
[p2addObserver:selfforKeyPath:@"per.name"options:0context:(__bridgevoid*)(KVO_CONTEXT_ADDRESS_CHANGED)];
[p2setValue:@"chutiyan"forKeyPath:@"per.name"];
UIButton*btn = [UIButtonbuttonWithType:UIButtonTypeCustom];
btn.frame=CGRectMake(100,100,100,40);
btn.backgroundColor= [UIColorgreenColor];
[self.viewaddSubview:btn];
[btnaddTarget:selfaction:@selector(btnClick)forControlEvents:UIControlEventTouchUpInside];
index=0;
[arraddObject:p2];
#endif
-(void)btnClick
{
for(Person*perinarr) {
[persetValue:[NSStringstringWithFormat:@"%ldName",index]forKeyPath:@"per.name"];
}
index++;
}
-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
if(context == (__bridgevoid*)(KVO_CONTEXT_ADDRESS_CHANGED)) {
NSString*name = [objectvalueForKeyPath:@"per.name"];
NSLog(@"%@",name);
}
}
-(void)dealloc
{
for(Person*perinarr) {
[perremoveObserver:selfforKeyPath:@"name"];
}
//[super dealloc];
}
原博客里举得例子比较好,我这个代码完全自己测试写的,贴上来为了自己以后好回忆,顺便看看代码思想有没有进步.