概述
KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则其观察者就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。
KVO其实也是“观察者”设计模式的一种应用。这种模式有利于两个类间的解耦合,尤其是对于 业务逻辑与视图控制 这两个功能的解耦合。
KVO 的具体实现
具体实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #import "ViewController.h" #import "Person.h"
@interface ViewController ()
@property (strong, nonatomic) Person *p1;
@end
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; self.p1 = [[Person alloc] init]; self.p1.name = @"p1"; [self.p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; self.p1.name = @"123"; }
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { NSLog(@"监听到了%@的%@属性发生了改变", object, keyPath); NSLog(@"%@", change); }
@end
|
1 2 3
| 打印结果: 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 是基于运行时实现的
1
| isa Class NSKVONotifying_Person 0x000001a12de2f545
|
上述例子中,当 p1.name
的值改变时,p1对象的 isa 指针会指向 NSKVONotifying_Person
,意味着,在程序运行时,会动态生成一个 NSKVONotifying_Person
类,该类继承于 Person,而且该类中也有个 -setName:
方法,方法中在设置 name 的同时实现了:
1 2 3 4 5 6 7 8 9
| - (void)setName:(NSString *)name { [super setName:name]; [self willChangeValueForKey:@"age"]; [self didChangeValueForKey:@"age"]; }
|