zoukankan      html  css  js  c++  java
  • iPhone KVO、KVC、KVB介绍

    先介绍几个关于Runtime System的概念:

      (1) isa指针:当一个对象被创建时,内存布局中的第一个元素是指向类结构的指针,即isa。通过isa指针,一个对象可以访问它的类结构,进而访问继承的类结构。

         (2) SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

         (3) IMP数据类型:它其实就是一个编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型(事实上,在Objective-C的编译器处理的时候,基本上都是C语言的。

    KVC、KVO、KVB概念区别

      通过名字看上去,这三种很相似,但是其并不一样,不过其作用也是相辅相成的。这些功能都由系统框架提供支持,使用也很方便。下面简单描述下:

      KVC就是类似使用[myObj setValue:key:]的方式去设置/获取属性值的操作方式

      KVB是用来绑定对象与观察者的

      KVO是观察者模式的一个改进版本,如果通过KVB绑定后,就可以通过KVO来获取对象属性更改的通知。

    KVO机制

      KVO(即Key-Value Observe)是cocoa针对观察者模式进行的改进,它提供了可以观察一个对象属性的方法,从而收到相应通知。这有点类似与NSNotification,但是NSNotification需要发送一个NSNotification对象,相比之下,KVO机制则显得更加简单。

    KVC实现分析

      KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

        比如说如下的一行KVC的代码:

      [site setValue:@"sitename" forKey:@"name"];

      就会被编译器处理成:

      SEL sel = sel_get_uid ("setValue:forKey:");

      IMP method = objc_msg_lookup (site->isa,sel);

      method(site, sel, @"sitename", @"name");

     如上,使用KVC在调用setValue:forKey:对象时,大概分成三个步骤:

    1. 获取SEL对象

    2. 通过sel对象和当前的isa指针,获取函数指针(IMP对象)

    3. 通过C函数指针的调用方式,直接调用函数(此处省去了发送消息的开销)

    KVB(Key-Value Binding)

    绑定,即为对象的观察者与被观察者之间建立联系。
    1. 为调用对象添加观察者

    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

    函数说明:

    observer-观察者对象

    keyPath-对象的key,需要观察的属性

    options-观察键值变化的几种可选方式

    context-可以传NULL,如果非NULL,则在观察者回调函数中会收到一些数据

    2. 观察者收到消息后的处理函数

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

    函数说明:

    keyPath-对象的key,需要观察的属性

    object-发送通知的对象

    change-包含变化之前与变化之后属性值的字典

    context-被观察者对象传入的context

    后续会介绍Runtime System,计划在此对KVO/KVC进行一些分析。

    可能包括如下:

    KVC属性查找逻辑

    KVO与观察者

    KVO与NSNotification

    by yytong

  • 相关阅读:
    Android 8.0编译过程
    Ubuntu下映射网络驱动器
    Android 指定调用已安装的某个“相机”App
    sendMessage 与 obtainMessage (sendToTarget)比较
    Linux tee命令
    Android P(9.0) userdebug版本执行adb remount失败
    adb shell get/setprop, setenforce...
    Bluedroid: 蓝牙协议栈源码剖析
    android o logcat read: unexpected EOF!
    Winform 打包 混淆 自动更新
  • 原文地址:https://www.cnblogs.com/ydhliphonedev/p/3018664.html
Copyright © 2011-2022 走看看