- Person类
@interface Person : NSObject
{
@public
NSString *name; // 成员变量
}
@property(nonatomic,copy)NSString *nickName; // 属性
@end
NSLog(@"----开始----");
self.p = [[Person alloc] init];
// 创建监听
NSKeyValueObservingOptions options = NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew;
[self.p addObserver:self forKeyPath:@"nickName" options:options context:@"Person.nickName"];
[self.p addObserver:self forKeyPath:@"name" options:options context:@"Person.name"];
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.p.nickName = @"昵称";
self.p->name = @"名字";
}
// 监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
NSLog(@"keyPath - %@",keyPath);
NSLog(@"object - %@",object);
NSLog(@"change - %@",change);
NSLog(@"context - %@",context);
}
-(void)dealloc
{
[self.p removeObserver:self forKeyPath:@"nickName"];
[self.p removeObserver:self forKeyPath:@"name"];
}
通过上面打印成员变量没有触发监听,这是因为KVO是通过重写setter方法来监听的,成员变量并没有setter方法
小结: 1.对象在执行KVO的addObserver后,会动态生成一个NSKVONotifying_Class的子类,并且在子类添加setKey方法(重写了setter方法) 2.同时当前对象的isa指向NSKVONotifying_Class子类 3.NSKVONotifying_Class子类的setter方法增加willChangeValueForKey和didChangeValueForKey方法 4.执行完removeObserver方法并没有删除NSKVONotifying_Class子类,只是isa指针又重新指回当前类