KVC和KVO原理解析

2017-08-09  本文已影响0人  stockholder

KVC 键值编码(Key-value coding)

KVC是一套方便我们用字符串来操作对象的机制,可以使得操作对象时跟操作字典一样的灵活。在字典转模型的领域中应用起来极为方便,并且KVC可以轻松的帮我们突破访问限制的一些问题,直接访问到私有成员

- (id)valueForKey:(NSString *)key;  
- (void)setValue:(id)value forKey:(NSString *)key; 
//如果需要操作访问一些“属性里的属性”时,就用带Path的方法来操作 
- (id)valueForKeyPath:(NSString *)keyPath;  
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
NSDictionary *dic = @{
                          @"name":@"test",
//KVC中,赋值时传入的值都只能是对象类型,无法直接传入基本数据类型
                          @"age":@18,
                          @"address":@"China"
                          };
    [p setValuesForKeysWithDictionary:dic];
    NSLog(@"name:%@ age:%ld address:%@",p.name,p.age,p.address);
@implementation Person {
    NSString *_address;
}

Person *p  =[[Person alloc] init];
[p setValue:@"China" forKey:@"address"];
NSString *ads = [p valueForKey:@"address"];

找的顺序是 setAddress:==>_address==>_isAddress==>address==>isAddress

  1. 用KVC赋值时,会优先调用set<Key>:属性值方法(setAddress:(NSString *)address)
  2. 如果找不到,则会先找带下划线的成员变量_<key>(_address),再找_is<Key>(_isAddress),如果找到则赋值
  3. 如果上面都找不到,则会先查找不带下划线的成员变量<key>(address),再找is<Key>(isAddress),找到则赋值
  4. 如果上面列出的方法或者成员变量都不存在,系统将会执行该对象的setValue:forUNdefinedKey:方法,默认是抛出异常
    5.如果想让这个类禁用KVC,那么重写+ (BOOL)accessInstanceVariablesDirectly方法让其返回NO即可,这样的话如果KVC没有找到set<Key>:属性名时,会直接用setValue:forUndefinedKey:方法.

KVO 键值观察Key-value observing)

简单的说就是在给某个类的属性添加观察的时候,系统就创建一个该类派生类,然后派生类重写该属性的setter方法实现观察对象的改变,然后将这个对象的 isa 指针指向这个派生类。对象就变成了新创建的子类的实例。
它是基于KVC实现的,实现了响应式编程,内部实现运用了runtime的特性。
下面这篇文章介绍了如何手动实现KVO
http://tech.glowing.com/cn/implement-kvo/

上一篇 下一篇

猜你喜欢

热点阅读