美文网首页
KVC和KVO原理解析

KVC和KVO原理解析

作者: stockholder | 来源:发表于2017-08-09 20:35 被阅读0次

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;
  • KVC的优点
    (1). 无论类中的成员是否私有,用KVC都可以对它们正常取值和赋值
    比如当属性在扩展里面 无法通过点语法赋值 可以通过kvc赋值
    (2). 不管你的成员变量是否加下划线,你用KVC取值和赋值时传入的属性名都可以不带下划线
    (3). 大大简化字典转模型代码,KVC提供了一套更简洁的操作方式,只需你传入一个字典,就可以帮你自动把字典里的每一项赋值给你实体类对应的属性
NSDictionary *dic = @{
                          @"name":@"test",
//KVC中,赋值时传入的值都只能是对象类型,无法直接传入基本数据类型
                          @"age":@18,
                          @"address":@"China"
                          };
    [p setValuesForKeysWithDictionary:dic];
    NSLog(@"name:%@ age:%ld address:%@",p.name,p.age,p.address);
  • KVC缺点:
    1.在编码时很容易输错key导致问题
    解决办法:用KVC时传入的Key必须保证类中存在同名的属性。否则会运行时崩溃。如果不希望运行时直接崩溃,就需要在类里重写setValue:值 forUndefinedKey:键方法,这样,当用KVC对Person对象赋值了一个Key与属性对应不上的错误时,系统会自动调用这个方法.
    2.语法相较点语法而言也略微繁琐。
    解决办法:用runtime取代

  • 实现方法:
    KVC运用了一个isa-swizzling技术,任何对象都有isa指针。KVC主要通过isa-swizzling,来实现其内部查找定位的:
    (1) 实例方法调用时,通过对象的 isa 在类中获取方法的实现
    (2) 类方法调用时,通过类的 isa 在元类中获取方法的实现

  • KVC的赋值原理:

@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 方法。自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。
    原来,这个中间类,继承自原本的那个类。不仅如此,Apple 还重写了 -class 方法,企图欺骗我们这个类没有变,就是原本那个类。

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

相关文章

  • KVC,KVO

    KVC , KVO KVC和KVO的区别及应用 KVC/KVO原理 1. KVC键值编码 KVC,即是指NSKey...

  • ios基础——KVO、KVC

    KVO和KVC常见问题: 1.KVC和KVO是什么.2.KVC和KVO的原理是什么3.KVC和KVO的使用场景4....

  • KVO和KVC的使用及原理解析

    一 KVO基本使用 二 KVO本质原理讲解及代码验证 三 KVC基本使用 四 KVC设值原理 五 KVC取值原理 ...

  • iOS-KVC和KVO

    重新整理一波KVO和KVC. 抛出几个常见问题 : 1.KVC和KVO是什么.2.KVC和KVO的原理是什么3.K...

  • KVC内部原理?KVC和KVO关系?

    KVC都不陌生,多多少少都用过,那么KVC内部原理是怎样的?KVC和KVO什么关系?使用KVC赋值会触发KVO吗?...

  • 常见面试题--KVC和KVO

    1、KVO实现原理 2、KVC原理

  • 面试题

    1.简述KVC和KVO,其中KVO实现原理? KVC : 键值编码(Key-Value Coding),它是一种通...

  • KVC/KVO原理

    KVC/KVO原理 KVC setValue:forKey原理 调用setValue:forKey:方法,会直接寻...

  • KVC

    KVC原理剖析 - CocoaChina_让移动开发更简单 iOS开发底层细究:KVC和KVO底层原理 | iOS...

  • KVC和KVO原理解析

    KVC 键值编码(Key-value coding) KVC是一套方便我们用字符串来操作对象的机制,可以使得操作对...

网友评论

      本文标题:KVC和KVO原理解析

      本文链接:https://www.haomeiwen.com/subject/rohqrxtx.html