美文网首页
OC 类的底层实现

OC 类的底层实现

作者: 我是晶锅 | 来源:发表于2019-03-11 16:54 被阅读0次

类的底层结构

和对象的底层一样,类对象前八个字节也是存的isa指针,那么第二个字节表示什么,我们可以直接找到源码,查看类结构。

  • 很明显,第一个指针是isa(注释掉,隐藏着的)
  • 第二个是superclass
  • 第三个cache,每一个类都会有一个cache,用来存储调用过的方法等,增加性能
  • 第四个最重要,bits,里面有我们类中的主要组成部分,看下面返回了data,接下来我们就看看data中有什么东东


    image.png

class_rw_t的结构

bits中返回了data,data的结构是class_rw_t,我们查看其中是什么样的结构,不进去不知道,一进去吓一跳,里面全是我们这个类中重要的信息。
调试时怎么进去呢?
通过类对象执行偏移进去的,想要进去data中的部分,将类对象指针向前偏移两位就可以了。
先看看其中结构吧:

image.png

没错,这里面有方法列表,属性列表,协议列表。
这里需要注意一下,readonly的属性和相关不可更改的都存在这里,这里的部分是不能进行修改的,当一个类创建完成的时候。
所以,类创建完成后,是不能添加ivar的了!


image.png

LLDB调试验证

看了源码中的代码,现在我们直接通过LLDB来调试验证正确性。
在已经导入源码的情况下,调试可以拿到底层数据结构中的对象。
1、拿到类对象,指针偏移两位,获取到data
2、打印data中所有数据,你能看到这个类的基本方法列表,属性列表和协议列表了


image.png

继续往里走,可以拿到我们自己创建的方法


image.png
通过这样的方式,我们还可以验证两个东西:
  • 类方法存在元类中
  • 实例方法存在类中

打印验证方法的获取

上面我们能够通过LLDB直接查看方法存的位置,类方法存在元类中,实例方法存在类中。(0表示有,1表示没有)
LGPerson中书写两个方法,并实现:

- (void)lg_instanceMethod;
+ (void)lg_classMethod;
demo1:class_getInstanceMethod
    Method method1 = class_getInstanceMethod([LGPerson class], @selector(lg_instanceMethod)); // 类对象 拿 实例方法
    Method method2 = class_getInstanceMethod(objc_getMetaClass("LGPerson"), @selector(lg_instanceMethod)); // 元类对象 拿 实例方法
    Method method3 = class_getInstanceMethod([LGPerson class], @selector(lg_classMethod));
    Method method4 = class_getInstanceMethod(objc_getMetaClass("LGPerson"), @selector(lg_classMethod));
    NSLog(@"%p-%p-%p-%p",method1,method2,method3,method4);

这里输出:1 0 0 1
解释:
对象方法是存在类中的,method1为1,method2为0;
类方法存在元类中的,method3为0,method4为1。

demo2:class_getMethodImplementation
    IMP imp1 = class_getMethodImplementation([LGPerson class], @selector(lg_instanceMethod));
    IMP imp2 = class_getMethodImplementation([LGPerson class], @selector(lg_classMethod));
    IMP imp3 = class_getMethodImplementation(objc_getMetaClass("LGPerson"), @selector(lg_instanceMethod));
    IMP imp4 = class_getMethodImplementation(objc_getMetaClass("LGPerson"), @selector(lg_classMethod));
    NSLog(@"%p-%p-%p-%p",imp1,imp2,imp3,imp4);

这里输出:1 1 1 1
解释:imp1 和 imp4与上面同理。为什么imp2 和 imp3也会有呢?其实类中并没有类方法,元类中也没有对象方法,只是 class_getMethodImplementation 底层会走 _objc_msgForward 方法,所以还是找到了。


image.png
demo3:class_getClassMethod
    Method method1 = class_getClassMethod([LGPerson class], @selector(lg_instanceMethod));
    Method method2 = class_getClassMethod(objc_getMetaClass("LGPerson"), @selector(lg_instanceMethod));
    
    // 类 --> lg_classMethod 类方法
    // 元类
    Method method3 = class_getClassMethod([LGPerson class], @selector(lg_classMethod));
    Method method4 = class_getClassMethod(objc_getMetaClass("LGPerson"), @selector(lg_classMethod));
    NSLog(@"%p-%p-%p-%p",method1,method2,method3,method4);

输出:0 0 1 1
解释:我们从底层源码中看出,class_getClassMethod 底层使用就是 class_getInstanceMethod

Method class_getClassMethod(Class cls, SEL sel)
{
    if (!cls  ||  !sel) return nil;

    return class_getInstanceMethod(cls->getMeta(), sel);
}

所以 method1 和 method2 中根本没有 lg_instanceMethod 的类方法,lg_instanceMethod 是一个对象方法。
method3 和 method4 其实都是从元类中找寻类方法,所以当然能找到。

添加方法,协议,属性 attachLists

我们的类,在创建类和需要添加的时候都会调用 attachLists 方法,将我们需要添加的方法,协议,属性添加进去。具体 attachLists 是怎么实现的,接下来分解。


image.png

最后附上一张类的底层结构图:


类结构.png

相关文章

  • OC对象的本质

    一、OC对象的底层实现 OC 中的代码在底层实现,使用的是 C、C++,所以要研究 OC 中的类结构,可以将 OC...

  • iOS底层初探

    OC底层实现原理 oc对象以及类的是底层实现 首先,通过数据结构的特性可以猜测类的底层应该是结构体这种数据结构,因...

  • oc对象本质

    OC代码底层实现都是c/c++,oc的类和对象都是基于c/c++的结构体实现的 1.nsobject的底层实现就是...

  • iOS OC对象总结

    OC的实现 OC的对象、类主要是基于C、C++的结构体来实现的。编写的 OC代码,底层实现其实都是C、C++代码。...

  • OC 类的底层实现

    类的底层结构 和对象的底层一样,类对象前八个字节也是存的isa指针,那么第二个字节表示什么,我们可以直接找到源码,...

  • iOS底层原理(一):OC的本质、KVO原理、Category原

    一、OC对象的本质 知识点 我们平时编写的OC代码,底层实现其实都是C\C++代码,OC的对象、类底层都是由C\C...

  • Objective-C 中类的数据结构

    一、类的结构 OC 中的代码在底层实现,使用的是 C、C++,所以要研究 OC 中的类结构,可以将 OC 的代码转...

  • 深入理解Objective-C中类的数据结构

    一、类的结构 OC 中的代码在底层实现,使用的是 C、C++,所以要研究 OC 中的类结构,可以将 OC 的代码转...

  • iOS底层 -- OC对象底层本质

    NSObject的底层实现 Student的底层实现 OC对象继承关系的底层实现

  • OC对象的本质

    一、OC对象的底层实现 Objective-C 底层是由C/C++的数据结构实现的。一个NSObject类对应C中...

网友评论

      本文标题:OC 类的底层实现

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