KVO和KVC的理解

KVO键值监听的使用
[A addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:@"123"];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)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:搜索方式


image.png

对象valueForKey:的搜索方式


image.png

数组、集合的 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。

你可能感兴趣的:(KVO和KVC的理解)