美文网首页
2018-03-29 KVC是怎么寻找Key的

2018-03-29 KVC是怎么寻找Key的

作者: 胡諾 | 来源:发表于2018-03-29 19:30 被阅读0次

KVC是怎么使用的,我相信绝大多数的开发者都很清楚,我在这里就不再写简单的使用KVC来设值和取值的代码了,首�先我们来探讨KVC在内部是按什么样的顺序来寻找key的。

设值

当调用setValue:属性值 forKey:@”name“的代码时,底层的执行机制如下:
• 程序优先调用set<Key>:属性值方法,代码通过setter方法完成设置。注意,这里的<key>是指成员变量名,首字母大小写要符合KVC的命名规则,下同

• 如果没有找到setName:方法,KVC机制会检查+ (BOOL)accessInstanceVariablesDirectly方法有没有返回YES,默认该方法会返回YES,如果你重写了该方法让其返回NO的话,那么在这一步KVC会执行setValue:forUndefinedKey:方法,不过一般开发者不会这么做。所以KVC机制会搜索该类里面有没有名为<key>的成员变量,无论该变量是在类接口处定义,还是在类实现处定义,也无论用了什么样的访问修饰符,只在存在以<key>命名的变量,KVC都可以对该成员变量赋值。

• 如果该类即没有set<key>:方法,也没有_<key>成员变量,KVC机制会搜索_is<Key>的成员变量。

• 和上面一样,如果该类即没有set<Key>:方法,也没有_<key>和_is<Key>成员变量,KVC机制再会继续搜索<key>和is<Key>的成员变量。再给它们赋值。

• 如果上面列出的方法或者成员变量都不存在,系统将会执行该对象的setValue:forUndefinedKey:方法,默认是抛出异常。

如果开发者想让这个类禁用KVC里,那么重写+ (BOOL)accessInstanceVariablesDirectly方法让其返回NO即可,这样的话如果KVC没有找到set<Key>:属性名时,会直接用setValue:forUndefinedKey:方法。

下面我们来让代码来测试一下上面的KVC机制

@interface Dog : NSObject@end@implementation Dog
{
     NSString* toSetName;
    NSString* isName;
    //NSString* name;
    NSString* _name;
    NSString* _isName;
}// -(void)setName:(NSString*)name{//     toSetName = name;// }//-(NSString*)getName{//    return toSetName;//}
+(BOOL)accessInstanceVariablesDirectly{
    return NO;
}
-(id)valueForUndefinedKey:(NSString *)key{
    NSLog(@"出现异常,该key不存在%@",key);
    return nil;
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
     NSLog(@"出现异常,该key不存在%@",key);
}@endint main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        Dog* dog = [Dog new];
        [dog setValue:@"newName" forKey:@"name"];
        NSString* name = [dog valueForKey:@"toSetName"];
        NSLog(@"%@",name);
    }
    return 0;
}

首先我们先重写accessInstanceVariablesDirectly方法让其返回NO,再运行代码(注意上面注释的部分),Xcode直接打印出

2016-04-15 15:52:12.039 DemoKVC[9681:287627] 出现异常,该key不存在name
2016-04-15 15:52:12.040 DemoKVC[9681:287627] 出现异常,该key不存在toSetName
2016-04-15 15:52:12.040 DemoKVC[9681:287627] (null)

这说明了重写+(BOOL)accessInstanceVariablesDirectly方法让其返回NO后,KVC找不到setName:方法后,不再去找name系列成员变量,而是直接调用setValue:forUndefinedKey:方法

所以开发者如果不想让自己的类实现KVC,就可以这么做。
下面那两个setter和getter的注释取消掉,再把

NSString* name = [dog valueForKey:@"toSetName"]; 换成 NSString* name = [dog valueForKey:@"name"];

XCode就可以正确地打印出正确的值了

2016-04-15 15:56:22.130 DemoKVC[9726:289258] newName

下面再注释掉accessInstanceVariablesDirectly方法,就能测试其他的key查找顺序了,为了节省篇幅,剩下的的KVC对于key寻找机制就不在这里展示了,有兴趣的读者可以写代码去验证。


本文作者:张元一

<上一篇 目录 下一篇>

相关文章

  • 2018-03-29 KVC是怎么寻找Key的

    KVC是怎么使用的,我相信绝大多数的开发者都很清楚,我在这里就不再写简单的使用KVC来设值和取值的代码了,首�先我...

  • 类添加属性的方法

    1、KVC,通过keyPath设置和读取(也可设置和读取一些未暴露的私有变量) KVC是怎么寻找Key的当调用se...

  • OC语法:KVC的底层实现

    一、KVC是什么二、怎么使用KVC三、KVC的底层实现四、KVC常见面试题 一、KVC是什么 KVC全称Key-V...

  • iOS---14---KVC

    [toc] 什么是KVC? KVC的全称key - value - coding,俗称 键值编码 ,可以通过key...

  • iOS原理篇(二): KVC实现原理

    KVC实现原理 什么是 KVC KVC基本使用 KVC 原理 总结 一 、 什么是KVC KVC的全称是Key-V...

  • KVC & KVO

    KVC - Key Value Coding 键值编码 一、KVC 简介 KVC 是一种可以直接通过字符串 key...

  • KVC分析

    KVC是什么? kvc 是key value coding 的缩写,在ios中用于通过key,来获取value,即...

  • KVC KVO

    1.什么是KVC和KVO? KVC:key value coder,键值编码,可以set或者get key对应的...

  • KVC & KVO

    一.什么是KVC KVC,key-value-coding,键值编码,即通过 key(属性名称)对 value(属...

  • KVC 与 KVO 使用姿势和原理解析

    KVC 什么是 KVC KVC 是 Key-Value-Coding 的简称。 KVC 是一种可以直接通过字符串的...

网友评论

      本文标题:2018-03-29 KVC是怎么寻找Key的

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