iOS相关知识(四)-- KVC相关

1、什么是KVC

KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性

2、常见的API有

//赋值方法
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
//取值方法
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key; 

forKey 和 forKeyPath 主要区别是路径区别如下

例:有2个类(Person和Dog)   Person类有2个属性 name 和 dog  Dog类 中也有一个name属性 如下:
        @interface FCPerson : NSObject
        @property(nonatomic,strong)NSString *name;
        @property(nonatomic,strong)Dog *dog;
        @end

        @interface Dog : NSObject
        @property(nonatomic,strong)NSString *name;
        @end

我们使用 setValue: forKey 对 Person name赋值 
使用 和 setValue: forKeyPath对 Dog  name赋值  如下所示:

    FCPerson * person = [[FCPerson alloc]init];
    person.dog = [[Dog alloc]init];
    [person setValue:@"张三" forKey:@"name"];
    [person setValue:@"小狗狗" forKeyPath:@"dog.name"];
    NSLog(@"人名:%@---狗名:%@",person.name,person.dog.name);

最后打印的结果就是 人名:张三---狗名:小狗狗
setValue: forKey 只能对person类的属性赋值 
如果想一层一层的对Dog类的属性进行赋值 就必须得用路径 setValue:forKeyPath 来赋值
如果直接使用 setValue: forKey 的方法对狗狗name赋值就会报错

所以:forKeyPath支持路径查找,forKey不支持

3、setValue:forKey:的原理如下图所示

setValue:forKey:的原理流程图.png

如上图所示:

使用KVC给属性赋值 首先会去寻找 这个属性的setter方法 即setKey
如果没有找到setKey则直接找_setKey
如果找到了则直接赋值,如果没有找到则会查看
accessInstanceVariablesDirectly方法的返回值(默认返回YES)

如果返回NO(不允许直接访问成员变量)调用setValue:forUndefinedKey:
并抛出异常NSUnknownKeyException

如果返回YES 则直接去找(顺序查找,上一个查不到就继续查找下一个)
_Key、
_isKey、
key、
isKey

如果都没有找到 则直接调用setValue:forUndefinedKey:
并抛出异常NSUnknownKeyException

4、valueForKey:的原理如下图所示

valueForKey:的原理.png
使用KVC获取属性的值 首先会去寻找 这个属性的getter方法即(顺序查找)
 getKey、
key、
isKey
_key

如果找到则直接调用方法
如果找不到则直接查看
accessInstanceVariablesDirectly方法的返回值(默认返回YES)

如果返回NO 调用调用valueForUndefinedKey:
并抛出异常NSUnknownKeyException

如果返回YES 则直接去找(顺序查找,上一个查不到就继续查找下一个)
_Key、
_isKey、
key、
isKey
如果找到则直接取值
如果都没有找到 则直接调用valueForUndefinedKey:
并抛出异常NSUnknownKeyException

5、通过KVC修改属性会触发KVO么?

答:会触发KVO

如果实现的setter方法就比较好理解,使用KVO就会触发KVO方法

如果没有 setter方法 KVC就会主动调用willChangeVlaueForKey 和didChangeVlaueForKey方法
从而触发了 KVO监听方法。(相当于手动调用)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,799评论 1 32
  • 一个NSObject对象占用多少内存? 系统分配了16个字节给NSObject对象(通过malloc_size函数...
    osnail阅读 923评论 0 0
  • 一、谈谈Runtime 1、OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行 2、OC的动态性...
    奋斗的小马达阅读 3,229评论 0 1
  • iOS底层原理总结--OC对象的本质(一) - 掘金 iOS底层原理总结--OC对象的本质(二) - 掘金 iOS...
    小李小李一路有你阅读 4,214评论 0 8
  • 无论是在我们的今后的工作当中还是面试找工作当中,这两个知识点是十分重要的,有些同学们对这方面的知识还是不是很了解,...
    __weak阅读 4,944评论 2 16