KVC俗称键值编码,可以通过一个key值来访问对象的某个属性。
常见的KVC API
赋值
- (void)setValue:(id)value forKey:(NSString *)key-
- (void)setValue:(id)value forKeyPath:(nonnull NSString *)keyPath
取值 - (id)valueForKey:(NSString *)key- (id)valueForKeyPath:(NSString *)keyPath
setValue:forKey:的原理
- 1、根据传入的key值,按照顺序
setKey:、_setKey:的顺序查找setter方法,如果找到,调用这个方法并将值传进去; - 2、如果没有找到setter方法,则查看
accessInstanceVariablesDirectly方法的实现,这个一个BOOL方法,如果这个类返回YES,则查找一个命名规则为_<key>、_is<key>、<key>、is<key>的成员变量,根据这个顺序,如果发现成员变量,则将value赋值给成员变量; - 3、如果没有发现setter或者其他实例变量,则调用
setValue:forUndefinedKey:方法,并默认退出异常。
valueForKey的原理
- 1、根据key值,按照顺序,查找
getKey、key、isKey、_key方法,如果找到了方法,调用方法取值; - 2、如果没有发现上述方法,则调用
accessInstanceVariablesDirectly,如果此方法返回YES,则按照顺序查找_<key>、_is<Key>、<key>、is<Key>成员变量,如果找到,调用方法取值; - 3、如果所有情况都失败,则调用
valueForUndefinedKey方法并抛出异常。
注意valueForUndefinedKey可以在子类中重写。
setValue:forKey:和setObject:forKey:的区别
setObject:forKey:是Foundation中Dictionary这个类中定义的,而setValue:forKey:是KVC定义的方法。
setObject:forKey:中key和value值都不能为nil,但是可以使[NSNull null],而setValue:forKey:value值可以为nil,但是key值不能为nil。但是value值为nil时,会调用removeObject:forKey方法。
在调用setValue:forKey:时,会先调用setObject:forKey:。如果setValue:forKey:value值为nil,则会调用removeObject:forKey方法。