美文网首页
iOS KVO原理

iOS KVO原理

作者: LT_9999 | 来源:发表于2022-07-13 07:04 被阅读0次

    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也一样

    相关文章

      网友评论

          本文标题:iOS KVO原理

          本文链接:https://www.haomeiwen.com/subject/whwisltx.html