KVC KVO总结

KVC基本概念:

a.kvc又称键值编码,是一种用于间接访问对象属性的机制,使用此机制不需要调用对象的存取(get和set)方法,也不用调用实例变量就能访问对象的属性,即使对象的属性为私有变量,kvc也能对此变量进行存取操作;

b.kvc的方法(-setValue: forKey: 和 -valueForKey:)有NSObject的非正式协议(类别)NSKeyValueCoding中被申明;


KVC的基本用法:

1.设置和访问:

kvc中的基本调用方法包括-setValue: forKey: 和 -valueForKey:这两个方法,他们以字符串形式向对象发送消息;

    例:
    Book *book = [[Book alloc] init];
    [book setValue:@"ios编程思想" forKey:@"bookName"];
    NSLog(@"book:%@",[book valueForKey:@"bookName"]);
是否存在setter  getter方法,如果不存在,将在内部查找名称为_key 或 key的实例变量,通过kvc,可以获取不存在getter方法的对象值,无需通过对象的指针访问。

需要注意的是,当我们通过setValue: forKey:设置对象的值或通过valueForKey:获取对象的值时,如果对象的实力变量为基本类型(char ,int ,float,bool),我们需要对数据进行封装


2.路径:方法(-setValue: forKeyPath: 和 -valueForKeyPath:)

除了通过key设置value外,kvc还支持路径,象文件路径一样,路径之间用" . "号隔开;

例:书对象中有个作者对象,作者对象中有name属性,通过book设置和获取到作者的name

	Book *book = [[Book alloc] init];
	[book  setValue:@"wxxu"  forKeyPath:@"author.name"];
	[book valueForKeyPath:@"author.name"];

3.一对多的关系:

如果向一个NSArray数组中请求一个键值,它会查询数组中所有的对象来查找这个键值,然后将查询的结果打包到另一个数组中返回;

例:假设book中有个NSArray数组 相关书籍(relativeBooks)属性,现在想获取所有相关书籍的名称(reBookName)(只是讲解问题,不考虑实际意义)

	Book *book = [[Book alloc] init];
	NSArray *reBooks = [NSArray arrayWithObjects:reBook1,reBook2,reBook3,nil];
	[book setValue:reBooks forKey:@"relativeBooks"];
	NSArray *bookNames = [book valueForKeyPath:@"relativeBooks.reBookName"];//获取到所有的相关书籍对象的reBookName

4.KVC的简单运算:

kvc还可以做一些简单的运算,如:求和(sum),最大值最小值(max   min),平均值(avg),个数(count)

用法:在以上关键字前加上@符号即可,然后加在你所求的属性前

例:求上面所有相关书籍的个数,总价格,最高价,最低价,平均价

Book *book = [[Book alloc] init];
[book valueForKeyPath:@"relativeBooks.@count"];//个数
[book valueForKeyPath:@"relativaBooks.@max.price"];//在price前加上@max求relativaBooks中price最大值,并返回最大值
[book valueForKeyPath:@"relativaBooks.@min.price"];//最小值
[book valueForKeyPath:@"relativaBooks.@avg.price"];//平均值
[book valueForKeyPath:@"relativaBooks.@sum.price"];//求和

KVO的基本概念:kvo使用了观察者模式,当被观察对象的属性发生变化时会通知观察者;

使用:kvo的使用简单的分为三步

1.注册观察者 2.实现回调方法(当被观察的属性发生变化时会回调此方法)3.移除观察者

实例:现在我们要观察Book对象的name属性(以下为伪代码,只为讲解知识点)

1.创建一个Book对象
@interface Book : NSObject{
	NSString * name;
	int 		price;
}
@end
2.假设现在要在一个Controller中观察Book对象中的name属性
注册观察者:你要观察哪个对象中的属性就用哪个对象注册观察者(如下面方法要观察Book中的name就用book调用addObserver方法),observer:参数是你在什么对象中实现回调,此处我们在self中实现回调,forKeyPath中是要观察的属性名称(如观察name属性就填入name,此处支持kvc中提到的路径),options中填的是你想把name的旧值传到回调方法中,还是传新值,或新旧值都传
Book *book =  [[Book alloc] init]; 
[book addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL]; 
3.实现回调 
方法的object参数就是观察的对象,此处是Book对象 ;change中能拿到修改前后的新旧数据(这要看注册观察者时传的是新值还是旧值,还是新旧都传)
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqualToString:@"name"])  //判断被观察的属性
    {
        myLabel.text = [stockForKVO valueForKey:@"price"];
    }
}
4.取消观察
[book removeObserver:self forKeyPath:@"name"];


注意:如果需要实现kvo,必须调用kvc的setValueForKey方法,或对象属性的set方法(如book.name = @"aaaa")来改变被观察对象的属性,才能触发kvo的回调方法

如果在Book对象直接修改(如name=@"changeName"),没有调用其set方法是不会触发kvo回调的

备注:以上为本人浅见,如有不对,希望各位大大们指出纠正,谢谢!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值