注:分析参考 MJ底层原理班 内容,本着自己学习原则记录
1 KVC 的基本使用
- 常用方法:(以下方法均是属于
NSObject(NSKeyValueCoding)
分类)
赋值
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
取值
- (nullable id)valueForKey:(NSString *)key;
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- 通过KVC修改属性
[person setValue:@10 forKey:@"age"];
[person setValue:@"DJ" forKeyPath:@"dog.name"];
- 通过KVC获取属性值
NSLog(@"%@", [person valueForKey:@"age"]);
NSLog(@"%@", [person valueForKeyPath:@"dog.name"]);
2 KVC 的底层原理
可以直接阅读
NSObject(NSKeyValueCoding)
分类中的注解,如第4点的引用说明图,下面是 MJ 底层课的图,图上描述的逻辑基本与官方说明一致。
2.1 赋值底层逻辑
摘自 MJ 底层课课件2.2 取值底层逻辑
摘自 MJ 底层课课件3 相关题
3.1 通过KVC修改属性会触发KVO么?
- 会触发KVO
-
通过 KVC 修改 person实例的 age 属性,触发 KVO
-
通过 KVC 修改 person实例的 age 实例变量,同样触发 KVO
通过实例直接修改实例变量不会触发 KVO。(参考《KVO底层实现分析》)
person->_age = 10;
为什么这里通过 KVC 修改实例变量就触发的呢?
实际是 KVC 的方法setValue:forKey:
或setValue:forKeyPath:
底层内部调用了willChangeValueForKey:
和didChangeValueForKey:
方法,效果就像手动触发 KVO 方式一样。
注意:KVO 查找
实例变量的命名类型
、 查找set<Key> 方法命名
的类型 和 查找get<key>方法命名
的类型,它们的类型在2.1和2.2中都有表示,查找是有顺序之分的。
3.2 KVC的赋值和取值过程是怎样的?原理是什么?
- 参考2.1和2.2
4 引用说明图(翻译成文字是不可能的啦😝)
-
- (void)setValue:(nullable id)value forKey:(NSString *)key;- (void)setValue:(nullable id)value forKey:(NSString *)key;
-
- (nullable id)valueForKey:(NSString *)key;-1- (nullable id)valueForKey:(NSString *)key;
-
@property (class, readonly) BOOL accessInstanceVariablesDirectly;
@property (class, readonly) BOOL accessInstanceVariablesDirectly;
注意:这里的
@property (class, readonly) BOOL accessInstanceVariablesDirectly;
表示的是一个类方法,property的括号中标注了class
文/Jacob_LJ(简书作者)
PS:如非特别说明,所有文章均为原创作品,著作权归作者所有,转载需联系作者获得授权,并注明出处,所有打赏均归本人所有!
网友评论