手撕iOS底层08 -- isa详解

449 阅读3分钟

通过之前对象的分析, 知道每一个OC对象里有一个isa的属性。通过isaISA_MASK的位与,得到一个指针地址

那这个地址是什么,它又有什么信息。这是本篇要探索的内容。


先贴上经典的isa流程图 ,本章将围绕这张图来阐述内容。

0x00 -- 对象的isa分析

  1. 通过LLDB打印输出,对象内存的这个首地址0x001d80010003b59存储的是属性isa

  2. 通过对isa属性与ISA_MASK的值按位与,得出shiftcls的地址,通过对地址打印,这个值是类对象的地址。

  3. 进一步反向证明,打印OtherObj.class的内存布局,类的首地址与对象的isa一毛一样。所以通过对象的isa可以找到它所属的类。


0x01 -- 类对象的isa的分析

struct objc_class : objc_object {
    // Class ISA;       // 8
    Class superclass;   // 8
    cache_t cache;      // 16        // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags 属性 方法 协议
  .....
}

进一步探索类对象的内存布局0x0000000100003b30类的首地址isa,第二个是父类superclass

  1. 通过类对象的isa的打印,输出依然是OtherObj,这个是OtherObj的元类
  2. 接着对元类isa打印输出,是NSObject,这个类是NSObject类吗?

通过调试,明显不是同一个NSObject类,那它是什么呢?

打印了NSObject类的元类,发现根类的地址和OtherObj元类的isa地址是一样的,叫根元类


0x02 -- 总结isa走位

对象的isa指向它的,

isa指向它的元类.

所有类的元类指向根元类.,

根元类指向自己,形成闭环,这里的根元类就是NSObject


0x03 -- superclassmetaclass继承关系

类(subclass)继承自它的父类(superclass)

父类最终会继承自根类(rootclass)

元类也有父类的继承关系, 一直继承到根元类(rootclass),根元类继承nil

Objective-C中的对象可以说是万物起源于NSObject.


子类的元类(metaclass)继承自父类的元类(meta superclass)

父类的元类最终会继承自根元类(root metaclass)

根元类(root metaclass)会继承自NSObject


通过以上的分析,万物皆是由NSObject创建,即万物皆对象.

验证class在内存中存在的个数。

Class cls1 = [Demo class];
Class cls2 = [Demo alloc].class;
Class cls3 = object_getClass([Demo alloc]);

通过以上获取类对象的地址,这些地址都是相同的, 说明在系统中只存在份。


面试题

  1. objc_classobjc_object的关系?
  • 结构体objc_class是继承自objc_object结构体,objc_object有一个isa属性,通过继承使objc_class也有了这个属性。
  • oc中定义一个对象,该对象满足objc_object特性, 也就是有isa属性。
  • NSObject是以objc_class为模版创建的,objc_class继承自objc_object,所以有isa属性。所以继承自NSObject的类也都继承了isa的这个属性。
  • 所以对象都有isa的属性, 表示当前isa的关系。 指向谁,属于谁。

  1. objc_object对象的关系?
  • 对象都是以objc_object为模版继承创建的。
  • OC层面上所有对象来自NSObject,但是真正到底层以c/c++语言的objc_object的结构体。
  • objc_object与对象的关系是继承的关系。

总结

在结构层面可以通俗的理解为上层OC底层的对接:

  • 下层通过结构体定义的模版,例如objc_class, objc_object
  • 上层是通过底层的模版的一些类型来创建, 如Person
  • 从以上所学可以看出在oc万物皆对象

objc_objectobjc_class之间整体关系


欢迎大佬留言指正😄,码字不易,觉得好给个赞👍 有任何表达或者理解失误请留言交流;共同进步;