1、当一个对象被观察时,runtime会动态自动创建继承该对象的类,
2、并重写被观察对象的setter和getter方法,setter负责调用原setter并通知所有观察对象值的改变;
3、 最后把该对象的指针指向这个创建的子类,对象就变成该子类的实例;
4、 如何创建手动触发KVO,在setter方法里手动实现
willChangeValueForKey 与 didChangeValueForKey
1. KVO是通过isa-swizzing的方法来实现的。就是比如B作为观察者观察A的属性name时,在运行时会动态生成一个A的子类notify_A类,然后将A类的实例对象的isa指针指向notify_A这个子类,然后在子类中重写的方法有三个
- (void) setName:(NSString*) name
{
willChangeValueForKey;
_name = name;
didChangeValueForKey;
}
2. 重写了class方法,返回的是原来的A类对象,这样的话内部再调用A类实例变量的其他方法时则不会发生问题。
class
{
return class_getSuperclass(object_getClass(self));
}
3. 重写了delloc方法,在合适的时候销毁这个运行时创建的类。
1.KVC与KVO的不同?
KVC(键值编码),即Key-Value Coding,一个非正式的Protocol,使用字符串(键)访问一个对象实例变量的机制。而不是通过调用Setter、Getter方法等显式的存取方式去问。
KVO(键值监听),即Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,对象就会接受到通知,前提是执行了setter方法、或者使用了KVC赋值。
2.和notification(通知)的区别?
notification比KVO多了发送通知的一步。两者都是一对多,但是对象之间直接的交互,notification明显得多,需要notificationCenter来做为中间交互。而KVO如我们介绍的,设置观察者->处理属性变化,至于中间通知这一环,则隐秘多了,只留一句“交由系统通知”,具体的可参照以上实现过程的剖析。
notification的优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,例如键盘、前后台等系统通知的使用也更显灵活方便。(参照通知机制第五节系统通知名称内容)
3.与delegate的不同?
和delegate一样,KVO和NSNotification的作用都是类与类之间的通信。但是与delegate不同的是:
这两个都是负责发送接收通知,剩下的事情由系统处理,所以不用返回值;而delegate 则需要通信的对象通过变量(代理)联系;
delegate一般是一对一,而这两个可以一对多。
4.涉及技术:
KVC/KVO实现的根本是Objective-C的动态性和runtime,以及访问器方法的实现;
总结:
对比其他的回调方式,KVO机制的运用的实现,更多的由系统支持,相比notification、delegate等更简洁些,并且能够提供观察属性的最新值以及原始值;但是相应的在创建子类、重写方法等等方面的内存消耗是很巨大的。所以对于两个类之间的通信,我们可以根据实际开发的环境采用不同的方法,使得开发的项目更加简洁实用。
另外需要注意的是,由于这种继承方式的注入是在运行时而不是编译时实现的,如果给定的实例没有观察者,那么KVO不会有任何开销,因为此时根本就没有KVO代码存在。但是即使没有观察者,委托和NSNotification还是得工作,这也是KVO此处零开销观察的优势。
异步:监听通知 主线程:发出通知 接收通知代码在主线程
主线程:监听通知 异步:发出通知 接收通知代码在异步
注意:在接收通知代码中 可以加上主队列任务
总结:接收通知代码 由 发出通知线程决定, KVO也一样
网友评论