概述
KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则其观察者就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。
KVO其实也是“观察者”设计模式的一种应用。这种模式有利于两个类间的解耦合,尤其是对于 业务逻辑与视图控制 这两个功能的解耦合。
KVO 的具体实现
具体实现代码如下:
#import "ViewController.h" #import "Person.h" @interface ViewController () /** p1 */ @property (strong, nonatomic) Person *p1; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 1.什么是通知 // 3个对象 self.p1 = [[Person alloc] init]; self.p1.name = @"p1"; // KVO是监听对象的属性值的改变的 [self.p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; self.p1.name = @"123"; } // 这个方法时属于 NSObject 类的,任何对象都可以作为观察者 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { NSLog(@"监听到了%@的%@属性发生了改变", object, keyPath); NSLog(@"%@", change); } @end |
打印结果:
2014-05-11 19:55:34.319 KVO和KVC和通知代理[559:109378] 监听到了<Person: 0x15ee2baa0>的name属性发生了改变
2014-05-11 19:55:34.320 KVO和KVC和通知代理[559:109378] 123
|
KVO 的实现原理
KVO 是基于运行时实现的
isa Class NSKVONotifying_Person 0x000001a12de2f545
|
上述例子中,当 p1.name
的值改变时,p1对象的 isa 指针会指向 NSKVONotifying_Person
,意味着,在程序运行时,会动态生成一个 NSKVONotifying_Person
类,该类继承于 Person,而且该类中也有个 -setName:
方法,方法中在设置 name 的同时实现了:
- (void)setName:(NSString *)name { [super setName:name]; // 这两个方法底层会调用observer的- (void)observeValueForKeyPath: ofObject: change: context:这个方法 [self willChangeValueForKey:@"age"]; [self didChangeValueForKey:@"age"]; } |