美文网首页iOS探索
深入了解iOS中的KVC

深入了解iOS中的KVC

作者: 雨月星缘 | 来源:发表于2018-12-16 15:53 被阅读0次

    KVC俗称键值编码,很多人都知道,也都用过,但是真的了解它的工作原理吗?

    简单来说,一个对象如果直接或间接继承自NSObject,那么它就遵守了NSKeyValueCoding协议,并且系统会对该协议中的方法提供一个默认实现。

    我们经常用的valueForKey:和valueForKeyPath:来获取值,就先来说说它们两个:

    1.valueForKey:通过给定的参数key,来查找对应的值,如果发现就返回,否则就会调用valueForUndefinedKey:方法,该方法的默认实现会抛出NSUndefinedKeyException异常。但是子类是可以重写该方法的。

    2.valueForKeyPath:通过给定的键路径,查找对应的值,如果找到就返回对应的值,否则也是执行valueForUndefinedKey:方法;其实该方法内部是调用valueForKey:来一步一步执行的。

    以上两种方法用着简单,但是我们应该知道他们是怎么工作的。
    第一步: 以get<Key>, is<Key>, <key>, <key>为名称来搜索访问器方法,如果找到就执行第五步,否则就执行第二步。
    第二步: 第一步没有找到,就搜索方法名为countOf<Key>, objectIn<Key>AtIndex:, <key>AtIndexes:。如果第一个方法存在,并且后两个方法至少有一个存在,那么就会创建一个能响应NSArray所有方法的集合代理对象,并返回。否则就执行第三步。
    第三步:该步会查找接收者是否实现了countOf<Key>, enumeratorOf<Key>, 和 memberOf<Key>:这三个方法。如果都实现了,就会创建一个能响应NSSet所有方法的集合代理对象,并返回。否则执行第四步。
    第四步: 该步骤首先查看接收者的类方法+ (BOOL)accessInstanceVariablesDirectly是否返回YES,如果返回YES,就会以
    <key>, _is<Key>, <key>, is<Key>为实例变量名来进行查找,找到的话就执行第五步,否则就执行第六步。
    第五步: 该步骤是对第一步和第四步查找到的值进行处理。
    (1). 如果值是标量并且被NSNumber类支持,系统会将其转换成对应的NSNumber对象并返回。
    (2). 如果值是标量但不被NSNumber类支持,系统会将其转换成对应的NSValue对象并返回。
    第六步: 如果以上步骤都失败,就会调用valueForUndefinedKey:方法。

    说完获取value,也要说说设置value:

    设置value可以通过setValue:forKey:和setValue: forKeyPath:

    1.setValue:forKey:是通过给定的key来对接收者进行查找,找到之后将value设置进去。
    2.setValue: forKeyPath:内部通过调用setValue:forKey:来进行设置

    注:以上两个方法没找到对应的key时,会调用setValue:forUndefinedKey:方法并抛出NSUndefinedKeyException异常

    setValue:forKey:和setValue: forKeyPath:的搜索规则就简单许多:

    第一步:通过set<Key>, set<Key>来查找存取方法,如果发现,调用它来设置值并结束。
    第二步:如果第一步没有找到,则调用接收者的+ (BOOL)accessInstanceVariablesDirectly,如果返回YES,则以
    <key>, _is<Key>, <key>, or is<Key>为实例变量名来进行查找,如果找到则设置相应的值并结束。
    第三步:如果以上都没有找到,就调用setValue: forUndefinedKey:方法。

    注意:如果一个类的某个属性是标量或者结构体,系统的默认实现会帮助我们处理对象与标量或结构体的转换。

    相关文章

      网友评论

        本文标题:深入了解iOS中的KVC

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