1.KVO的实现原理
KVO-键值观察机制,原理如下:
-
1.当给A类添加KVO的时候,runtime动态的生成了一个子类NSKVONotifying_A,让A类的isa指针指向NSKVONotifying_A类,重写class方法,隐藏对象真实类信息
-
2.重写监听属性的setter方法,在setter方法内部调用了Foundation 的 _NSSetObjectValueAndNotify 函数
-
3._NSSetObjectValueAndNotify函数内部
a) 首先会调用 willChangeValueForKey
b) 然后给属性赋值
c) 最后调用 didChangeValueForKey
d) 最后调用 observer 的 observeValueForKeyPath 去告诉监听器属性值发生了改变 .
- 4.重写了dealloc做一些 KVO 内存释放
2.KVO使用
KVO在iOS中是观察者模式的一种表现。我们可以使用KVO让某个对象成为另外一个对象的监听者。当被监听对象的属性发生改变时,KVO就会通知监听者。
关于KVO的使用网上有很多教程,KVO使用主要是三个步骤:
调用addObserver:forKeyPath:options:context:注册成为监听者。
监听者实现observeValueForKey:ofObject:change:context:方法。
调用removeObserver:forKeyPath:移除监听
前面说过KVO的实现是建立在KVC的基础上的。即被监听的属性必须能满足KVC的,才能是用KVO来监听。
一 、KVO的自动触发监听通知的方法系列:
// Call the accessor method.
[account setName:@"Savings"];
// Use setValue:forKey:.
[account setValue:@"Savings" forKey:@"name"];
// Use a key path, where 'account' is a kvc-compliant property of 'document'.
[document setValue:@"Savings" forKeyPath:@"account.name"];
// Use mutableArrayValueForKey: to retrieve a relationship proxy object.
Transaction *newTransaction = <#Create a new transaction for the account#>;
NSMutableArray *transactions = [account mutableArrayValueForKey:@"transactions"];
[transactions addObject:newTransaction];
二、KVO的手动触发监听通知:
// 关闭balance的自动触发
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {
BOOL automatic = NO;
if ([theKey isEqualToString:@"balance"]) {
automatic = NO;
}
else {
automatic = [super automaticallyNotifiesObserversForKey:theKey];
}
return automatic;
}
要实现手动触发监听,你要执行在变更前执行willChangeValueForKey:方法,在变更后执行didChangeValueForKey:方法:
- (void)setBalance:(double)balance {
[self willChangeValueForKey:@"balance"];
_balance = balance;
[self didChangeValueForKey:@"balance"];
}