方法:
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key;
key和keyPath的区别:
- key只能放当前对象的属性,如:“age”;
- keyPath可以路径,如:“student.age”;
setValue:forKey: 赋值的原理
- 第一步,按顺序查找
setKey:、_setKey:方法; - 都没找到,查看
accessInstanceVariablesDirectly方法返回值是否为YES; - 如果是,则继续按顺序查找:
_key、_isKey、key、isKey; - 如果布尔值为
NO,或者最后还是没查找到对应的方法,则抛出异常:setValue:forUndefinedKey:。
value:forKey: 获取值的原理
- 第一步,按顺序查找
getKey:、key:、isKey:、_key:方法; - 都没找到,查看
accessInstanceVariablesDirectly方法返回值是否为YES; - 如果是,则继续按顺序查找:
_key、_isKey、key、isKey; - 如果布尔值为
NO,或者最后还是没查找到对应的方法,则抛出异常:valueForUndefinedKey:。
扩展
1、通过KVC修改属性,会触发KVO吗?
- 会。
原理:
[person setValue:@10 forKey:@"age"]的底层实现:
[person willChangeValueForKey:@"age"];person->_age = 10;[person didChangeValueForKey:@"age"];
而didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法,即:KVO。