KVC : 键值编码(Key Value Coding)
简介
一个非正式的协议,不通过调用setter,getter方法,而是提供一种机制来间接访问对象,几乎所有的ObjC对象都支持KVC操作
详解
在C#中可以通过反射读写一个对象的属性,可以通过字符串的方式去动态的控制一个对象,但是ObjC的语言特性,你不必进行任何操作就可以进行属性的动态读写,ObjC主要是基于Smalltalk进行设计的,有很多动态特性,动态类型,动态加载,动态绑定等
KVC的操作方法是由NSKeyValueCoding协议提供,因为NSObject提供了这个协议,所以几乎ObjC对象都支持KVC操作
使用方法
- 动态设置key值
- 动态读取key值
优势: 减少代码量
代码实现一 : 用于简单路径
1.people.m类中,按KVC说法,有一个Value对应着height的key
这里说的key只是一个字符串,它对应的值是可以是任意类型的对象
@implementation people
{
int _height;
}
@end
2.在ViewController中,因为people类中的height没有setter和getter方法,我们是无法读写的,但通过KVC,我们可以实现对height的读写
- (void)viewDidLoad
{
[super viewDidLoad];
people *p = [[people alloc] init];
NSLog(@"p init height =%@", [p valueForKey:@"height"]);
[p setValue:[NSNumber numberWithInt:168]forKey:@"height"];
NSLog(@"p height = %@", [p valueForKey:@"height"]);
}
代码实现二 : 用于复合路径
KVO : 键值监听(Key Value Observing)**
简介
也是一个非正式的协议,是一种观察者模式,它是基于KVC实现的关键技术之一,能够观察一个对象key path(属性)值的变化,几乎所有的ObjC对象都可以使用KVO
详解
利用KVO可以很容易的实现视图组件和数据模型的分离,当数据模型的属性值改变后,作为监听器的视图组件就会被激发,激发时回调监听器自身.
很多框架都有双向绑定机制,如果数据模型修改后,会立即反映到UI视图上,ObjC原声就支持这种机制,即KVO
KVO的操作方法由NSKeyValueObserving协议提供,也是NSObject实现了这个协议,所以几乎所有的ObjC对象都可以使用KVO
使用方法
- 实现观察:为被监听对象(通常是数据模型)注册监听器
- 在被观察的key path的值变化时调用
- 停止观察:删除指定Key路径的监听器
优势: 在开发时节省不必要的代码,提高了开发效率
代码实现一 : 监听对象属性值变化
一.people类
@interface people : NSObject
@property (nonatomic, copy)NSString *name;
@end
二.ViewController实现
1.声明对象
#import "people.h"
@interface ViewController ()
{
people *_myPeople;
}
- (void)viewDidLoad
{
_myPeople = [[people alloc] init];
_myPeople.name = @"qianqian";
}
2.为myPeople对象添加一个观察者,监听"name"属性的变化
addObserver 观察者
forKeyPath 被监听的属性值
options 监听改变前的值还是改变后的值
context 可以传参数值
[_myPeople addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:@"lala"];
3.利用KVO监听到对象的属性值发生改变时,调用下面方法
keyPath 哪个属性被改了
object 哪个对象的属性被改了
change 改成了什么样子
context 添加监听时context的参数值
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"keyPath是%@,object是%@,change是%@,context是%@",keyPath,object,change,context);
}
4.对象属性值改变,两种改变方式
1._myPeople.name = @"daqianqian";
2.[_myPeople setValue:@"daqianqian" forKey:@"name"];
5.在不需要时移除监听器,当然,你也可以在改变完属性值后remove,看个人需要
- (void)delloc
{
[_myPeople removeObserver:self forKeyPath:@"name" context:nil];
}
代码实现二 : 监听对象变量变化
一.people.m类中
@implementation people
{
int _height;
}
@end
二.ViewController实现
1.声明对象
_myPeople = [[people alloc] init];
不给int类型赋值则默认为0
2.为myPeople对象添加一个观察者,监听"height"变量的变化
[_myPeople addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionOld context:@"lala"];
3.利用KVO监听到对象的变量值发生改变时,调用下面方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"keyPath是%@,object是%@,change是%@,context是%@",keyPath,object,change,context);
}
4.对象变量值改变,只有KVC一种改变方式
[_myPeople setValue:[NSNumber numberWithInt:5] forKey:@"height"];
5.在不需要时移除监听器
- (void)delloc
{
[_myPeople removeObserver:self forKeyPath:@"height" context:nil];
}
注意
KVO是以添加观察者之前的值为基准
下面的结果为5
_myPeople = [[people alloc] init];
[_myPeople setValue:[NSNumber numberWithInt:5] forKey:@"height"];
[_myPeople addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionOld context:@"lala"];
[_myPeople setValue:[NSNumber numberWithInt:2] forKey:@"height"];
网友评论