3.取消注册观察removeObserver:forKeyPath:context:
Demo:
@interface myPerson : NSObject
{
NSString *_name;
int _age;
int _height;
int _weight;
}
@end
@interface testViewController : UIViewController
@property (nonatomic, retain) myPerson *testPerson;
- (IBAction)onBtnTest:(id)sender;
@end
- (void)testKVO
{
testPerson = [[myPerson alloc] init];
[testPerson addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"height"]) {
NSLog(@"Height is changed! new=%@", [change valueForKey:NSKeyValueChangeNewKey]);
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (IBAction)onBtnTest:(id)sender {
int h = [[testPerson valueForKey:@"height"] intValue];
[testPerson setValue:[NSNumber numberWithInt:h+1] forKey:@"height"];
NSLog(@"person height=%@", [testPerson valueForKey:@"height"]);
}
- (void)dealloc
{
[testPerson removeObserver:self forKeyPath:@"height" context:nil];
[super dealloc];
}
第一段代码声明了myPerson类,里面有个_height的属性。在testViewController有一个testPerson的对象指针。
在testKVO这个方法里面,我们注册了testPerson这个对象height属性的观察,这样当testPerson的height属性变化时, 会得到通知。在这个方法中还通过NSKeyValueObservingOptionNew这个参数要求把新值在dictionary中传递过来。
重写了observeValueForKeyPath:ofObject:change:context:方法,这个方法里的change这个NSDictionary对象包含了相应的值。
需要强调的是KVO的回调要被调用,属性必须是通过KVC的方法来修改的,如果是调用类的其他方法来修改属性,这个观察者是不会得到通知的。
3、NSNotification的用法见http://www.easck.com/eduora_meimei/article/details/44198909
区别:
delegate 的 优势 :
1.非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。
2.如果delegate中的一个方法没有实现那么就会出现编译警告/错误
3.协议必须在controller的作用域范围内定义
4.在一个应用中的控制流程是可跟踪的并且是可识别的;
5.在一个控制器中可以定义定义多个不同的协议,每个协议有不同的delegates
6.没有第三方对象要求保持/监视通信过程。










