KVC的全称是Key-Value Coding,即"键值编码",可以通过一个key来访问某个属性。
常用的Api有:
// 通过key来设置instance对象的属性的值
- (void)setValue:(id)value forKey:(NSString *)key;
// 通过keyPath来设置instance对象的属性的值的值(有个对象cat是instance对象的属性,该对象有个属性high),keyPath为@"cat.high"
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forUndefinedKey:(nonnull NSString *)key;
// 通过key来获得instance对象的属性的值
- (id)valueForKey:(NSString *)key;
// 同理keyPath
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForUndefinedKey:(NSString *)key;
G、题:通过KVC修改属性会触发KVO吗?
答:会触发KVO的。虽然说如果没有写属性,使用代码直接给成员变量赋值是不会触发KVO的,但是,如果使用KVC修改成员变量的值,是会触发KVO的。这是KVC的内部机制所导致的(KVC内部调用了手动触发KVC的机制即willChangeValueForKey
和didChangeValueForKey
)。在didChangeValueForKey
的里面触发KVO监听。
H、题:KVC赋值和取值过程是怎样的?原理是什么?
答:
setValue:forKey:
的赋值原理:
- 按照
setKey:
、_setKey
的顺序查找方法; - 如果找到方法,则传递参数,调用方法;
- 如果没找到方法,则查看
accessInstanceVariablesDirectly
方法的返回值; - 如果返回值为
NO
,则会调用setValue:forUndefinedKey:
方法,并抛出异常,NSUnknownKeyException
。 - 如果返回值为
YES
,则按照_key
->_isKey
->key
->isKey
的顺序查找成员变量; - 如果查找到了上述4个中的一个,直接赋值;
- 如果都没找到,则会调用
setValue:forUndefinedKey:
方法,并抛出异常,NSUnknownKeyException
。
注意:accessInstanceVariablesDirectly
这个方法的默认返回值为YES
valueForKey:
的取值原理:
- 按照
getKey:
、key
、isKey
、_key
的顺序查找方法; - 如果找到方法,则直接调用方法;
- 如果没找到方法,则查看
accessInstanceVariablesDirectly
方法的返回值; - 如果返回值为
NO
,则会调用valueForUndefinedKey:
方法,并抛出异常,NSUnknownKeyException
。 - 如果返回值为
YES
,则按照_key
->_isKey
->key
->isKey
的顺序查找成员变量; - 如果查找到了上述4个中的一个,直接取值;
- 如果都没找到,则会调用
valueForUndefinedKey:
方法,并抛出异常,NSUnknownKeyException
。
网友评论