一、介绍各自的用法
KVO
当对象的某一个属性发生变化的时候,我们得到一个相应的通知。
eg:
KVOObject* kvo= [[KVOObject alloc]init];
kvo.name = @"abc";//在声明文件中声明了name属性。所以直接使用点语法赋值
[kvo addObserver:teacher //kvo为事件的监听者,此处就是注意谁监听谁实现后边的 监听触发以后的方法。
forKeyPath:@"name" //便是监听的哪一个属性
options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld//得到什么值
context:nil];
声明以后 如果KVOObject.name的值做修改 ,则会自动调用KVOObject.mm中的方法 (eg:kvo.name = @"123")
//KVOObject.mm
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"keyPath:%@, object:%@ change:%@ context:%@",keyPath,object,change,context);
//change的值
change:{
kind = 1;
new = 123;
old = abc;
}
}
NSNotification 通知
NSNotification的对象很简单,就是poster要提供给observer的信息包裹。
eg 1 监听系统的方法的时候
监听键盘显示的时候
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow) name:UIKeyboardDidShowNotification object:nil];
需要定义响应方法
-(void)keyboardDidShow
{
NSLog(@"键盘弹起");
}
eg 2 监听自定义name方法的时候
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(testNotification) name:@"Test" object:nil];
//post消息 来通知系统中心响应 监听的方法
KVC是一种间接访问对象属性的机制,而不是直接通过设置器和访问器或者点语法来访问对象属性
二、两者的优缺点
1)KVO的使用:
被观察者发出
然后只要被观察者的keyPath值变化(注意:单纯改变其值不会调用此方法,只有通过getters和setters来改变值才会触发KVO),就会在观察者里调用方法observeValueForKeyPath:ofObject:change:context:
因此观察者需要实现方法
-
这 些代码都只需在观察者里进行实现,被观察者不用添加任何代码,所以谁要监听谁注册,然后对响应进行处理即可,使得观察者与被观察者完全解耦,运用很灵活很 简便;但是KVO只能检测类中的属性,并且属性名都是通过NSString来查找,编译器不会帮你检错和补全,纯手敲所以比较容易出错。
2)NSNotification的使用 这里的通知不是由被观察者发出,而是由NSNotificationCenter来统一发出,而不同通知通过唯一的通知标识名notificationName来区分,标识名由发送通知的类来起。 首先被观察者自己在必要的方法A里,通过方法postNotificationName:object:来发出通知notificationName这样发送通知者这边的工作就完成了,每次A被调用,就会发送一次通知notificationName。 然后谁要监听A的变化,就通过[NSNotificationCenter defaultCenter]的方法addObserver:selector:name:object:为观察者注册监听name为notificationName的通知然后每次发出name为notificationName的通知时,注册监听后的观察者就会调用其自己定义的方法notificationSelector来进行响应。 NSNotification的特点呢,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但是其优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活