KVC的赋值方式
当调用setValue:forKey:方法时,底层的执行机制如下:
1.程序优先调用setValue:forKey:时,代码通过setter方法完成设置。
2.如果没有找到setValue:forKey:方法,KVC机制会检查+(BOOL)accessInstanceVariablesDirectly方法有没有返回YES,默认该方法会返回YES,如果你重写了该方法让其返回NO的话,那么这一步KVC会执行setValue:forUndefinedKey:方法,不过一般开发者不会这么做。所以KVC机制会搜索该类里面有没有命名为目标值的成员变量,无论该变量是在类接口部分定义,还是类实现部分定义,也无论用了什么样的访问修饰符,只在存在已存在的变量,KVC都可以对该成员变量赋值。
3.如果该类既没有set:方法,也没有_成员变量,KVC机制会搜索_is的成员变量。
4.和上面一样,如果该类既没有set:方法,也没有is和成员变量,KVC机制再会继续搜索和is的成员变量。再给它们赋值。
5.如果上面列出的方法或者成员变量都不存在,系统将会执行该对象的setValue:forUndefinedKey:方法,默认是抛出异常(大部分情况下,我们没有重载这个方法,程序是会直接carsh的)
如果想让这个类内部禁用KVC,那么重写+ (BOOL)accessInstanceVariablesDirectly方法让其返回NO即可,这样的话如果KVC没有找到set:属性名时,会直接用setValue:forUndefinedKey:方法。
KVC的取值方式
当调用valueForKey:的代码时,KVC对key的搜索方式不同于setValue:属性值 forKey:,其搜索方式如下:
1、首先按get<你的key>、<你的key>、is<你的key>的顺序查找getter方法,找到直接调用。如果是bool、int等内建值类型,会做NSNumber的转换。
2、上面的getter没有找到,查找countOf<你的key>、objectIn<你的key>AtIndex:、<你的key>AtIndexes格式的方法。 如果countOf<你的key>和另外两个方法中的一个找到,那么就会返回一个可以响应NSArray所有方法的代理集合(collection proxy object)。发送给这个代理集合(collection proxy object)的NSArray消息方法,就会以countOf<你的key>、objectIn<你的key>AtIndex:、<你的key>AtIndexes这几个方法组合的形式调用。还有一个可选的get<你的key>:range:方法。
3、还没查到,那么查找countOf<你的key>、enumeratorOf<你的key>、memberOf<你的key>:格式的方法。如果这三个方法都找到,那么就返回一个可以响应NSSet所有方法的代理集合(collection proxy object)。发送给这个代理集合(collection proxy object)的NSSet消息方法,就会以countOf<你的key>、enumeratorOf<你的key>、memberOf<你的key>:组合的形式调用。
4、还是没查到,那么如果类方法accessInstanceVariablesDirectly返回YES,那么按_<你的key>,_is<你的key>,<你的key>,is<你的key>的顺序直接搜索成员名。
5、再没查到,调用valueForUndefinedKey:。
网友评论