zoukankan      html  css  js  c++  java
  • 你不知道的KVO的内部实现

    通过强大的Runtime 实现。第一次观察某个Object 时,runtime 会创建一个新的继承自 object 对应Class 的 subClass。在这个新subClass 里它重写了被观察的key(属性)的setter 方法。然后将object 指向原来对应Class 的isa指针指向了新创建的subClass【原因很简单,实例对象保有变量,而向对象发消息实际是那isa 去类对象里找对应的实例方法去了。即重写的setter 方法】;

          这些被重写的setter 实现了如何通知观察者们。

    有意思的是:ios 不希望这个机制暴露在外。除了setter ,这个动态生成的subClass 同时也重写了  -class  方法,依旧返回原先的class. 不知细看的话,被kvo 过得object 看起来和原先的object 没什么两样。【而实际是object 所指向的类 及里面的有些实例方法 变了】。

    关于代码验证可见:    http://limboy.me/ios/2013/08/05/internal-implementation-of-kvo.html

    KVC 实现原理:http://blog.csdn.net/wzzvictory/article/details/9674431

    可以不用他那个gcc 编译,在自己项目的main.m 里替换下。会有两个错。

    obj - > isa   可以用 object_getClass(obj) 替换也是一样的。

    阅读这篇文章发现一个有趣的现象:

    [obj class]   和 object_getClass(obj)  有什么区别 

    如:

        Class obj = [NSObject class];

        Class cls = object_getClass(obj);

        Class cls2 = [obj class];

        NSLog(@"%p",cls);

        NSLog(@"%p",cls2);

        NSLog(@"%p",obj);

    你会发现什么? 打印的 cls 和 cls2 不同。 and 

        NSObject *obj1 = [NSObject new];

        Class cls3 = object_getClass(obj1);

        Class cls4 = [obj1 class];

        NSLog(@"%p",cls3);

        NSLog(@"%p",cls4);

    对比下~~~

    这个问题留待下一遍 介绍 。

     

     

  • 相关阅读:
    Ubuntu Server下docker实战 02: docker进阶配置
    Ubuntu Server下docker实战 01: 安装docker
    简单一个方法实现商品组合管理--递归笛卡尔
    Little-Endian小字节序
    BinaryWriter和BinaryReader用法
    C#位运算
    TCP协议三次握手过程分析
    简述HTTP过程
    c# 版贪食蛇
    今日头条列表json
  • 原文地址:https://www.cnblogs.com/DamonTang/p/3851601.html
Copyright © 2011-2022 走看看