美文网首页iOS开发技巧
OC底层原理04—类、元类、根元类 与 isa的关联

OC底层原理04—类、元类、根元类 与 isa的关联

作者: 夏天的枫_ | 来源:发表于2020-09-15 00:16 被阅读0次

如题,今天来探究下类的一些信息,isa指针的指向就是该类对象的元类,每一个类都是它的元类的对象,元类是对类对象的描述。首先来分析一下代码

//类对象内存存在个数为 1
void lgTestClassNum(){
    Class class1 = [LGPerson class];
    Class class2 = [LGPerson alloc].class;
    Class class3 = object_getClass([LGPerson alloc]);
    Class class4 = [LGPerson alloc].class;
    NSLog(@"\n%p-\n%p-\n%p-\n%p",class1,class2,class3,class4);
}

void lgTestNSObject(){
    // NSObject实例对象
    NSObject *object1 = [NSObject alloc];
    // NSObject类
    Class class = object_getClass(object1);
    // NSObject元类
    Class metaClass = object_getClass(class);
    // NSObject根元类
    Class rootMetaClass = object_getClass(metaClass);
    // NSObject根根元类
    Class rootRootMetaClass = object_getClass(rootMetaClass);
    NSLog(@"\n%p 实例对象\n%p 类\n%p 元类\n%p 根元类\n%p 根根元类",object1,class,metaClass,rootMetaClass,rootRootMetaClass);
}

打印结果分析之:

2020-09-14 23:24-isa分析[1763:92018] <LGPerson: 0x102055210>
2020-09-14 23:24-isa分析[1763:92018] 
0x100002588-
0x100002588-
0x100002588-
0x100002588
2020-09-14 23:24-isa分析[1763:92018] 
0x1005135b0 实例对象
0x7fffb1bd0140 类
0x7fffb1bd00f0 元类
0x7fffb1bd00f0 根元类
0x7fffb1bd00f0 根根元类

可以看到lgTestClassNum中打印的类对象地址都是同一个,说明:类对象存在个数仅有一份。在lgTestNSObject中实例对象地址与类的地址,以及元类、根元类、根根元类的地址是不一样的,其中元类、根元类、根根元类的地址则是一样的。这是为什么呢?
在系列文章前几章中我们了解了isa的结构,类的首地址就是isa,isa中的shiftcls存储着类的一些信息,isa在类中存在这非常重要的关系,继续通过LLDB分析之。

isa在类中用lldb分析
isa指向:对象->类对象->元类对象->根元类对象,根元类对象的isa指向根元类自身
元类可以存储类的自有信息,可供子类继承的类信息。
实例对象没有继承关系,只有类与类间才有继承关系;
根元类的父类为NSObject,NSObject 继承的地址没有,所以父类为nil。
经典isa走位图
实例对象的isa指向它的类对象Subclass,Subclass继承自它的父类Superclass,而Subclass的isa指向它的元类Subclass(meta),类和元类的地址是一样的。

拓展:objc_class vs objc_object 关系?

  • 类的底层编码是—— objc_class
  • 对象的根对象—— objc_object
  • objc_class 又继承自 objc_object ,所有class也是对象——万物皆对象。
  • 所有的对象,类,元类都有isa。
    结构体类型objc_class 继承自objc_object类型,其中objc_object也是一个结构体,且有一个isa属性,所以objc_class也拥有了isa属性
    mian.cpp底层编译文件中,NSObject中的isa在底层是由Class 定义的,其中class的底层编码来自 objc_class类型,所以NSObject也拥有了isa属性
    NSObject 是一个类,用它初始化一个实例对象objc,objc 满足 objc_object 的特性(即有isa属性),主要是因为isa 是由 NSObject 从objc_class继承过来的,而objc_class继承自objc_object,objc_object 有isa属性。所以对象都有一个 isa,isa表示指向,来自于当前的objc_object
    objc_object(结构体) 是 当前的 根对象,所有的对象都有这样一个特性 objc_object,即拥有isa属性

objc_object 和实例对象的关系?

所有的对象都是继承NSObject,NSObject又继承自底层的objc_object(C/C++)结构体类型,底层的是没有对象而是结构体。

类的内存 + 对象的内存

class_data_bits_t
先拓展:内存偏移

  • 常量地址,差4个字节,连续的地址存储,优化存储。
  • 对象的指针地址,&p 指针的指针,
  • 数组指针
    数组首个元素的指针地址作为数组的指针地址
    通过首地址的偏移,可挨个取出数组元素,偏移量则由元素类型的字节数决定。

再来分析下类objc_object的结构信息

// 注意new 、old版本差,此版本为objc4-781
struct objc_class : objc_object {
    // Class ISA;  // 默认8字节
    Class superclass;  // 8字节
    cache_t cache;  // 8 + 4 + 2 + 2      // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

    /*篇幅有限,省略N多代码,主要代码分析上面即可*/
};

class_data_bits_t存储了类中的属性(property)、方法(method)、协议(protocol),这是类结构信息中的关键部分,通过之前的LLDB我们是可以获得类对象的首地址的,通过内存偏移的方式获取class_data_bits_t
思路是:isa 8字节 + superClass 8字节 + cache_t(mask_t : 4 + buckerts : 8 + xxx :2 + xxx:2 = 16)。
isa属性:继承自objc_object的isa,占 8字节
superclass 属性:Class类型,Class是由objc_object定义的,是一个指针,占8字节
cache属性:简单从类型class_data_bits_t目前无法得知,而class_data_bits_t是一个结构体类型,结构体的内存大小需要根据内部的属性来确定,而结构体指针才是8字节
bits属性:只有首地址经过上面3个属性的内存大小总和的平移,才能获取到bits

通过LLDB分析:


获取ro_or_rw信息 打印propertylist

781没有了propertylis, methodlist, protocllist. p $x 打印的是类型(刀x:是地址的别名)

相关文章

  • OC底层原理04—类、元类、根元类 与 isa的关联

    如题,今天来探究下类的一些信息,isa指针的指向就是该类对象的元类,每一个类都是它的元类的对象,元类是对类对象的描...

  • 3.isa

    isa指向 ->实例isa -> 类|类isa -> 元类 | 元类isa -> 根元类|根元类isa -> 根元...

  • isa

    NSObject的父类为nil NSObject的isa为根元类 元类的isa都为根元类 根元类的isa为本身 根...

  • isa的流程和类的继承

    isa的指向流程: NSObejct:实例对象的isa指向 元类,元类的isa指向根元类,根元类的isa指向自己 ...

  • iOS开发中方法查找流程图

    实例对象的isa指针指向类对象,类对象的isa指针指向元类,元类的isa指针指向根元类,根元类的isa指针指向自己...

  • OC底层原理07 - objc_class 中 cache 原理

    在OC底层原理05 - isa与类关联的原理[https://www.jianshu.com/p/4656390f...

  • 类对象、元类

    任何实例的isa指针指向其类对象,类对象的isa指针指向其元类对象,元类对象的isa指针指向根元类对象,根元类对象...

  • isa指针?(对象的isa,类对象的isa,元类的isa都要说)

    对象的isa指针指向所属的类类的isa指针指向了所属的元类元类的isa指向了根元类,根元类指向了自己。 类的sup...

  • isa指针的作用

    原文:iOS面试题大全 对象的isa指向类,类的isa指向元类(meta class),元类isa指向元类的根类。...

  • iOS 对象和isa指针详解

    一个objc对象的isa指针指向他的类对象,类对象的isa指针指向他的元类,元类的isa指针指向根元类,所有的元类...

网友评论

    本文标题:OC底层原理04—类、元类、根元类 与 isa的关联

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