美文网首页
深挖iOS底层-类(4)

深挖iOS底层-类(4)

作者: Alex1989 | 来源:发表于2020-12-09 18:20 被阅读0次

深挖iOS底层-类底层(4)

通过LLDB探究类地址:

-w653

经过上述不同打印都可以拿到类的首地址。

继续深入探究首地址:


-w910

通过上述打印,得知类的收地址是2250, 2228是元类。

元类

元类的创建都是由编译器自动完成。

  • 元类刨根问底


    -w801

通过LLDB不断获取首地址得到根元类:NSObject
追溯过程:
类isa 指针 -> 类(LGPerson) ->元类(LGPerson) -> NSObject(根元类)

类对象([object class])

-w762
  • 地址不同?类对象到底有几份?
    验证类对象:


    -w869

    利用各种类的打印,验证类对象在内存中只存在一份

isa指针的指向(探究根元类)

探究NSObject过程


-w592

superClass的继承

实例对象之间没有任何关系, 只有类和类之间单纯的继承关系,元类也存在继承,根元类指向NSObject。
最经典的解析图:


-w556

此图完整诠释了,isa指针指向和类的继承关系。

Class,NSObject,objc_class和底层objc_object的关系

  • 通过源码得知objc_object 本质是结构体,也称根对象,所有对象都会满足此继承关系


    -w954
  • objc_class是objc_object类型
    如图

    -w842
  • 所有类,对象,元类 都是以objc_object类型的继承过来,objec底层编译就是objc_object.


    -w617
  • objc_object结构体包含isa ,objc_class与bjc_object是继承关系因此也有isa,同理所有实例对象,类,元类都继承自objc_object,有isa(isa是Class类型的)

    -w841
  • Class底层是 objc_class类型:


    -w392

    Class是objc_class类型,深入objc_class

  • 探究objc_class的类型

老版源码objc_class源码实现(已经弃用)


-w606

新版本的objc_class源码实现


-w705

我们发现新版源码结构体继承 objc_object,因为这是c++结构体 并且结构体内有一些函数。

  • 举例探究objc_class


    -w660

    LLDB调试已经帮我们探究类对象的具体结构是什么样子的,类对象的首地址存放isa指针,第二个地址存放的继承的类

简单捋下指针和指针的作用

-w777

从上图可以看出a和b就是int类型的指针,都存放着tmp的内存地址,也叫a和b指向tmp的地址,指针的作用就是存地址。

对象创建的内存演算

-w954

p1,p2指针:在栈区,都为 1级指针 负责指向 堆区的对应地址

LGPerson:负责给堆区开辟 p1 和 p2指向的内存

堆区的两片内存:存放的是对象的内容,对象的首地址是isa指向的是父
类LGPerson,对象的首地址isa指针存储是LGPerson相关信息。

最左侧的两片内存地址是p1和p2的二级指针,存放的是p1,p2的内存地址。

数组指针

连续排列的地址,声明的数组的指针指向首地址,也就是首个个元素的地址。如下图:


-w943

通过lldb控制台看出,通过地址的偏移,依然可以取到元素。
数组内存布局示意图:


-w571

探索类(object_class)的内存布局:

-w648

class地址 :2250 16进制偏移得到2270:32字节转化为16进制 (1-F(0-15))
根据bit.data获取bits内容


-w628
  • 根据bits信息中(class_rw_t类)中 methods(),properties(),protocols() 探索属性列表,方法列表,协议列表


    -w607
  • 我们来通过LLDB完整的演算一下objc_object类型的内存布局


    -w888
  1. 先获取类对象的地址
  2. 偏移32字节后,得到bits 转换成bits类型
  3. bits是class_data_bits_t类型深入class_data_bits_t源码


    -w674

    通过bits调用data()方法 就获取到了class_rw_t类型的变量,通过此变量就能获取到methods(),properties(),protocols() 。
    获取方法列表(也可以获取属性列表,协议列表)
    举个例子:
    OC类的属性和方法:


    -w426
  • 属性列表推导


    -w657

方法列表推导


-w542
  • 方法列表中也会同时生属性的set,get方法。


    -w589

相关文章

网友评论

      本文标题:深挖iOS底层-类(4)

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