11. KVC And KVO
1. KVC And KVO 的认识
KVC/KVO是观察者模式的一种实现 KVC全称是Key-value coding,翻译成键值编码。顾名思义,在某种程度上跟map的关系匪浅。它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制。KVO全称是Key-value observing,翻译成键值观察。提供了一种当其它对象属性被修改的时候能通知当前对象的机制。再MVC大行其道的Cocoa中,KVO机制很适合实现model和controller类之间的通讯。
2. KVC And KVO 的使用
首先我们创建一个Egg类,给它赋值一个属性
@interface Egg : NSObject
@property (nonatomic ,copy)NSString *weight;
@end
@implementation Egg
@end
然后我们在创建一个JianBingGuoZi类 (名字随便起的),给它设置几个属性,其中一个是刚才我们定义的Egg
#import "Egg.h"
@interface JianBingGuoZi : NSObject
@property (nonatomic, strong)Egg *egg;
@property (nonatomic, copy)NSString *name;
@property (nonatomic, assign) int price;
@property (nonatomic, copy)NSString *decr;
@end
@implementation JianBingGuoZi
@end
在程序启动的跟视图
- (void)viewDidLoad {
[super viewDidLoad];
_egg = [[Egg alloc] init];
_egg.weight = @"80克";
_jian = [[JianBingGuoZi alloc] init];
_jian.name = @"水果馅的煎饼";
_jian.price = 5;
_jian.egg = _egg;
// 1. 使用KVC获取数据
[self useKVCGetData];
// 2. 使用KVC批处理数据
[self usePiChuLi];
// 3. 链性访问
[self useKeyPath];
// 4. KVO的使用
[self useKVO];
}
- (void)useKVO
{
// 给一个对象添加监听
// 1. 谁去监听
// 2. 监听那个属性
// 3. 监听到对象属性改变的时候传递数据是什么数据
[_jian addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
// 监听的对象 如果属性发生变化就会调用这个方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@---%@",change[@"new"],change[@"old"]);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[_jian setValue:@"狗肉馅的煎饼" forKeyPath:@"name"];
[_jian setValue:@"这是一个煎饼,不是饺子" forUndefinedKey:@"description"];
}
- (void)useKeyPath
{
// 设置属性值
[_jian setValue:@"200克" forKeyPath:@"egg.weight"];
// 获取属性值
[_jian valueForKeyPath:@"egg.weight"];
}
- (void)usePiChuLi
{
// 1. 同时获取对象的多个属性
NSArray *array = [NSArray arrayWithObjects:@"name",@"price", nil];
NSDictionary *dict = [_jian dictionaryWithValuesForKeys:array];
// 2. 同时给对象的多个属性赋值
NSDictionary *dictT = @{
@"name":@"老鼠肉馅的煎饼",
@"price":[NSNumber numberWithInt:15]
};
[_jian setValuesForKeysWithDictionary:dictT];
}
- (void)useKVCGetData
{
// 1.valueForKey 首先查找以name或者isName命名的getter方法,如果没有这个方法,去对象内部查找名字为name或者_name命名的实例变量
NSString *name = [_jian valueForKey:@"name"];
// 2. KVC 自动包装功能,自动将基本数据类型包装成NSNumber 或者 NSValue 对象
[_jian valueForKey:@"price"];
// 设置属性值 首先查找以setName命名的setter方法,如果没有这个方法,去对象内部查找名字为name或者_name命名的实例变量
[_jian setValue:@"猪肉馅的煎饼" forKey:@"name"];
}
- (void)dealloc
{
// 移除监听
[_jian removeObserver:self forKeyPath:@"name"];
}
@end
3. 拓展
有时候后台给我们传过来的参数包含有关键字,我们在赋值的时候会出错,比如
但是我们又不能让后台去改返回的数据,这时候我们就可以这么写,把属性名字更改
然后再重写这个方法就行了