KVC,KVO的区别和使用

KVC/KVO的理解

字数703 阅读12 评论0 

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];

}

原博客里举得例子比较好,我这个代码完全自己测试写的,贴上来为了自己以后好回忆,顺便看看代码思想有没有进步.

原文地址:https://www.cnblogs.com/zhufeng1994/p/5603193.html