1.KVC(间接访问对象属性)
以字符串的形式向对象发送消息
(使用这个机制不需要调用set或者get方法来访问成员变量,它是通过setValue:forKey:和valueForKey:方法)
对对象的属性进行赋值和取值
(setValue:ForKey:和setValue:ForKeyPath:)
缺点:如果key写错,编译时不会报错,运行时会报错
触发KVC:通过setValue:forKey:和valueForKey:方法
2.KVO(监听属性变化、传值、一键换肤)
定义
键值观察观察属性的值,当指定对象的属性被修改后,该对象就会收到通知。
①(==注册观察者==)被观察者发出addObserver:forKeyPath
②(==添加回调函数==)被观察者的keyPath值发生变化(通过get和set来改变值才会触发),就会在观察者里调用方法observeValueForKeyPath
③==销毁观察者==
KVO是什么?内部是怎么实现的?
kvo,全称Key-Value Observing,它提供了一种方法,==当对象某个属性发生改变时,就会自动通知相应的观察者==。
当一个对象使用了KVO监听,iOS系统会==修改这个对象的isa指针==,改为指向一个全新的通过Runtime动态创建的子类,该子类拥有自己的set方法实现,set方法实现内部会顺序调用willChangeValueForKey方法、原来的setter方法实现、didChangeValueForKey方法,而didChangeValueForKey==方法内部又会调用监听器的==observeValueForKeyPath:ofObject:change:context:监听方法。
补充
如何触发KVO:只有通过set和get来改变值才会触发
KVO监听self.name和_name的结果?
_name属性不会走到KVO的回调方法,KVO只有通过get和set来改变值才会触发
如何手动触发KVO
被监听的属性的值被修改时,就会自动触发KVO。如果想要手动触发KVO,则需要我们自己调用willChangeValueForKey和didChangeValueForKey方法即可==在不改变属性值的情况下手动触发KVO==,并且这两个方法缺一不可。
3.self.name 调用实质
self.name 生成带下划线name的成员变量.
4.在某个方法中self.name=_name,name=_name他们有区别吗?为什么
前者是存在内存管理的Set方法赋值,它会对_name对象进行保留或者拷贝操作
后者是普通赋值
一般来说,在对象的方法里成员变量和方法都是可以访问的,我们通常会重写Setter方法来执行某些额外的工作。比如说,外部传一个模型过来,那么我会直接重写Setter方法,当模型传过来时,也就是意味着数据发生了变化,那么视图也需要更新显示,则在赋值新模型的同时也去刷新UI。
5.self.name打点调用和下划线的区别
self.name 是对属性的访问,实质上是在调Set和Get方法,会使引用计数增加
_name 是对局部变量的访问,不会调用Set和Get方法,不会使引用计数增加