两个问题作为引导:
1. 通过KVC修改属性是否触发KVO?
2. KVC的赋值、取值过程是什么样的?原理是什么?
KVC是什么:
Key-Value-Coding 也就是可以通过一个key来访问、修改某个属性
常见API:
-setValue:forKeyPath:更强大,可访问当前对象中的对象的属性。
-setValue:forKey:只可访问当前对象的属性
-valueForKeyPath:
-valueForKey:
forKeyPath 的注意一定要先确保属性对象的存在,然后才能set值成功。如下:
MJPerson *person = [[MJPerson alloc] init];
person.cat = [[MJCat alloc] init];
[person setValue:@10 forKeyPath:@"cat.weight"];
1. 通过KVC修改属性是否触发KVO?
答:会触发。
我们先了解KVC的设值过程,假使没用set方法时,其内部属性变化也会触发KVO。原理就是KVC内部实现有实现手动调用KVO方法。
∴ 我们可以猜测[person setValue:@10 forKey:@"age"];
的伪代码如下:
[person willChangeValueForKey:@"age"];
person->_age = 10;
[person didChangeValueForKey:@"age"];
2. KVC的赋值、取值过程是什么样的?原理是什么?
setValue:forKey流程是什么,即KVC赋值原理?
先找setKey:方法
再找_setKey:方法
再看AccessInstanceVariableDirectly 如果为NO 则报错。 如果为YES则依次查找_key、_isKey、key、isKey如果这几个都没用则报错。
流程图解释:

ValueForKey:流程是什么,即KVC取值原理?
先顺序查找 getKey:,key,isKey,_key
如无 则再 accessInstanceVariableDirectly 判断
如果YES 则依次按照 _Key、_isKey、key、isKey进行查找
流程图解释:

网友评论