KVO && KVC
Posted Jk_Chan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KVO && KVC相关的知识,希望对你有一定的参考价值。
KVO:
- key-value observing
- 当指定的对象的属性被修改后,则对象就会接受到通知。
- 简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者。
- 使用步骤:
- 1.注册,指定被观察者的属性(由被观察者主动添加观察自己的观察者)
- 2.实现回调方法
- 3.移除观察
- 使用范例:
- @interface StockData : NSObject {
- NSString * stockName;
- float price;
- }
- @end
- @implementation StockData
- @end
- - (void)viewDidLoad {
- [super viewDidLoad];
- stockForKVO = [[StockData alloc] init];
- [stockForKVO setValue:@"searph" forKey:@"stockName"];
- [stockForKVO setValue:@"10.0" forKey:@"price"];
- //往StockDat对象上添加观察者
- [stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
- myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];
- myLabel.textColor = [UIColor redColor];
- myLabel.text = [stockForKVO valueForKey:@"price"];
- [self.view addSubview:myLabel];
- UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- b.frame = CGRectMake(0, 0, 100, 30);
- [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
- [self.view addSubview:b];
- }
- -(void) buttonAction {
- [stockForKVO setValue:@"20.0" forKey:@"price"];
- }
- //作为一个KVO的观察者需要实现回调
- -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
- if([keyPath isEqualToString:@"price"]) {
- myLabel.text = [stockForKVO valueForKey:@"price"];
- }
- }
- //最后需要移动观察者
- - (void)dealloc {
- [stockForKVO removeObserver:self forKeyPath:@"price"];
- }
KVC:
- KeyValueCoding的简称
- 一种使用字符串标识符,间接访问对象属性的机制,而不是通过调用Setter、Getter方法访问。
- 即使对象中的成员变量不是属性,也可以通过KVC读写成员变量值
- 使用方法:
- 关键方法:
- NSKeyValueCodingprotocol
- 获取值:
- valueForKey:(NSString *)属性的名字
- valueForKeyPath:(NSString *)传入属性的路径,xx.xx形式。
- valueForUndefinedKey
- 默认实现是抛出异常,可以重写这个函数做错误处理。
- 修改值
- setValue:forKey:
- setValue:forKeyPath:
- setValue:forUndefinedKey:
- setNilValueForKey:
- 当对非类对象属性设置nil时,调用,默认抛出异常。
- 一对多关系成员的情况
- mutableArrayValueForKey:
- 有序一对多关系成员 NSArray
- mutableSetValueForKey:
- 无序一对多关系成员 NSSet
- 示范例子:
- Person类
- @implementation Person
- @synthesize name,age;//属性name 将被监视
- -(void) changeName{
- [email protected]"changeName directly";
- }
- @end
- PersonMonitor类 监视了name属性
- @implementation PersonMonitor
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
- if ([keyPath isEqual:@"name"]) {
- NSLog(@"change happen, old:%@ new:%@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey]);
- }
- }
- @end
- //测试代码
- //初始化被监视对象
- Person *p =[[Person alloc] init];
- //监视对象
- PersonMonitor *pm= [[PersonMonitor alloc]init];
- //KVO
- [p addObserver:pm forKeyPath:@"name" options:(NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld) context:nil];
- //测试前的数据
- NSLog(@"p.name is %@",p.name);
- //KVC
- //通过setvalue 的方法,PersonMonitor的监视将被调用
- [p setValue:@"name kvc" forKey:@"name"];
- //查看设置后的值
- NSLog(@"p name get by kvc is %@",[p valueForKey:@"name"]);
- //效果和通过setValue 是一致的
- [email protected]"name change by .name=";
- //通过person自己的函数来更改name
- [p changeName];
- /*
- 结果输出
- 2011-07-03 16:35:57.406 Cocoa[13970:903] p.name is name
- 2011-07-03 16:35:57.418 Cocoa[13970:903] change happen, old:name new:name kvc
- 2011-07-03 16:35:57.420 Cocoa[13970:903] p name get by kvc is name kvc
- 2011-07-03 16:35:57.421 Cocoa[13970:903] change happen, old:name kvc new:name change by .name=
- 最后一次修改是直接修改 所以没法产生通知
- */
以上是关于KVO && KVC的主要内容,如果未能解决你的问题,请参考以下文章