KVC KVO Notification
2016-05-07 本文已影响19人
Luyize
一、KVC(key value code)的基本概念和用法
1、基本概念
1)键-值编码是一个用于间接访问对象属性的机制,使用该机制不需要调用存取方法和变量实例就可以访问对象属性
2)通过KVC可以给readonly的属性赋值,
3)如果对象属性为基本数据类型时,我们存的时候需要将数据封装为NSNumber类型,系统内部存取时,系统会自动封装/解封
4)如果没有用@property声明,他讲在内部查找名为_key或key的实例变量
5)路径
除了通过键值设置值外,键/值编码还支持指定路径,通过.号隔开
6)一对多的关系
如果向NSArray请求一个键值,它实际上会查询数组中的每个对象来查找这个键值,然后将查询结果打包到另一个数组中并返回给你。
7)可以应用字符做简单运算,sum/min/max/avg/count
8)存取值格式
存值
setValue:forKey:
setValue:forKeyPath:
取值
valueForKey:
valueForKeyPath:
2、适用情况:将服务器的内容转化为数据模型,能够简化代码
3、练习
定义一个Person对象,他叫乔布斯,他有许多苹果设备:
1个macbook,价格8000
1个iPhone, 价格5000
1个iPad, 价格3800
使用kvc为Person设置名字, 使用kvc计算乔布斯所有设备的总价。
Person *jobs = [[Person alloc]init];
[jobs setValue:@"jobs" forKey:@"name"];
AppleDevice *macBook = [[AppleDevice alloc]init];
macBook.name = @"macBook";
macBook.price = 8000;
AppleDevice *iPhone = [[AppleDevice alloc]init];
iPhone.name = @"iPhone";
iPhone.price = 5000;
AppleDevice *iPad = [[AppleDevice alloc]init];
iPad.name = @"iPad";
iPad.price = 3800;
jobs.deviceArray = @[macBook,iPhone,iPad];
NSNumber *deviceSumPrice = [jobs valueForKeyPath:@"deviceArray.@avg.price"];
二、KVO(Key-Value-Observer)的基本概念和用法
1、基本概念
一种使对象获取其他独享的特定属性变化的通知机制
2、适用情况
主要用于试图,交互方面,比如界面的某些数据变化了,界面的显示也需要跟着变化,就需要建立数据和界面的关联
3、实现步骤
1)采用下面这个方法给属性添加观察者,在哪里注册观察者就要在哪里移除观察者
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
2)观察者实现下面方法,如果监听的属性发生变化,便会调用该方法。
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context;
3)个人习惯在delloc中释放
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context;
4、练习:
监听狗的动作,做相应的回应
三、通知的基本概念和用法
1、基本概念
1)一种一对多的信息广播机制,一个应用程序同时只能有一个NSNotificationCenter对象
2)任何人都可以发送任何消息到消息中心,识别感兴趣通知的标示就是object+通知名称
2、适用情况
类与类之间传递信息
3、实现步骤
1)添加通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(paySalary) name:@"发工资啦" object:nil];
/*
* [NSNotificationCenter defaultCenter]:创建一个单例通知中心,NSNotificationCenter表示通知中心的一个类
* self: 指别人发送信息的对象
* selector: 收到别人发送的信息后,通知中心要做的事情
* name: 指定通知的唯一标识符
* object: 如果object指定了内容,发送信息时也要指定同样的object,否则无法接收信息,如果设为nil,则表示任何人都可以给发送信息
*/
2)实现添加通知时方法选择器选择的方法
3)在需要发送通知的类中采用下面方法发送通知,发送成功便会执行步骤二实现的方法
[[NSNotificationCenter defaultCenter] postNotificationName:@"发工资啦" object:nil];
4)移除通知
[[NSNotificationCenter defaultCenter] postNotificationName:nil object:nil userInfo:nil];
四、练习
模拟应用程序的通知
- (void)watchDog:(Dog *)dog{
_dog = dog;
/*
* _dog:指定观察哪个对象
* self: 谁观察dog
* face: 指定观察dog对象的哪个属性
* OptionNew | OptionOld:当属性变化时,将新值和旧值都传给方法
* context: 参数
*/
//让主人监听狗的表情
[_dog addObserver:self forKeyPath:@"face" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
//让主人监听狗的动作
[_dog addObserver:self forKeyPath:@"action" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
//如果监听的属性发生变化,便会调用该方法。
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context{
if([keyPath isEqualToString:@"face"]){
if ([change[@"new"] isEqualToString:@"smaile"]) {
NSLog(@"狗由%@变化为%@",change[@"old"],change[@"new"]);
NSLog(@"给一块肉");
}
}else if ([keyPath isEqualToString:@"action"]){
if ([change[@"new"] isEqualToString:@"汪汪汪"]) {
NSLog(@"狗由%@变化为%@",change[@"old"],change[@"new"]);
NSLog(@"打一顿");
}
}
}
//当主人对象被释放后移除观察着
- (void)dealloc{
[_dog removeObserver:self forKeyPath:@"face"];
[_dog removeObserver:self forKeyPath:@"action"];
}