KVO键值监听的使用
[A addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:@"123"];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
NSLog(@"监听到%@的%@属性值改变了 - %@ - %@", object, keyPath, change, context);
}
KVO是OC观察者模式的又一实现,使用了isa混写来实现的KVO
KVO原理
1.运行时会创建一个NSKVONotifying_A的子类,并将监听对象的A的isa指针指向这个NSKVONotifying_A的子类
2.在这NSKVONotifying_A的内部重新这个setter方法
- (void)setValue:(NSString *)value
{
[self willChangeValueForKey:value];
_value = value;
[self didChangeValueForKey:value];
}
3.didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法
几个注意点
- 使用KVC改变值,KVO可以观察到变化
- 修改成员变量的值,KVO观察不到,必须添加KVO手动实现,willChangeValueForKey,didChangeValueForKey
- 使用setter方法改变值KVO才能生效
KVC键值编码的使用
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key;
KVC
setValue:forKey:搜索方式
对象valueForKey:的搜索方式
数组、集合的 valueForKey:的搜索方式
1、首先按getKey,key,isKey,_key的顺序查找getter方法,找到直接调用。如果是BOOL、int等内建值类型,会做NSNumber的转换。
2、上面的getter没找到,查找countOfKey、objectInKeyAtindex、KeyAtindexes格式的方法。如果countOfKey和另外两个方法中的一个找到,那么就会返回一个可以响应NSArray所有方法的代理集合的NSArray消息方法。
3、还没找到,查找countOfKey、enumeratorOfKey、memberOfKey格式的方法。如果这三个方法都找到,那么就返回一个可以响应NSSet所有方法的代理集合。
4、还是没找到,如果类方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey,key,iskey的顺序搜索成员名。
5、再没找到,调用valueForUndefinedKey。