相关文章推荐

ios-类的加载过程(_read_images/懒加载类/非懒加载类)

上篇文章分析了 read_images 中的模块含义,实现了 非懒加载类 懒加载类 加载到内存的过程。其中遗留上了一个问题 methodizeClass 方法的实现,本篇文章着重分析 methodizeClass 方法和 分类 的加载过程。

分类的本质:

首先通过clang -rewrite-objc main.m -o main.cpp 看下结构

分类的本质,就是一个 _category_t类型的结构体

methodizeClass

  • 进入 **methodizeClass** 源码,获取要研究的对象
  • rwe中添加方法列表,属性列表,协议
  • attachToClass实现

    rwe的逻辑已methodList为例

    rwe的逻辑如下

    获取 ro->baseMethods()

    通过 prepareMethodLists 方法排序

    rwe->methods.attachLists 插入

    排序prepareMethodLists方法探究

  • prepareMethodLists
  • fixupMethodList
  • 验证方法排序
  • 查看kc_ro内容

    查看经过 **prepareMethodLists** 方法过后排好序的第一个方法

    在控制台打印方法列表

    按照方法名称排序

    按照方法imp地址排序

    attachLists:插入

  • **method_list_t** 继承与 **entsize_list_tt** ,是一个二维数组
  • attachLists实现
  • 断点进入要研究的对象 LGPerson attachLists 方法中打个断点

    继续断点跟进

    由上图可看出,方法列表是如何插入到内存的, hasArray() 同理

    所以 加载类 是一个一维赋值,路径为: map-images -> _read_images -> readClass -> realizeClassWithoutSwift -> mehodizeClass -> prepareMethodLists -> fizupMethodList -> attachToClass -> load_categories_nolock -> attachCategories -> extAllocIfNeeded -> ectAlloc -> attachLists

    attachCategories分析

    继续执行一步,打印mlist

    把mlist插入到定义的64位数组的末尾部

    rwe -- LGB分类数据加载

    进入** attachLists **方法进行内存加载

    综上所述, attachLists 方法主要是 将类 和 分类 的数据加载到rwe

    首先加载类的 data 数据, rew 没有值, list 为空,走的是首地址赋值, 一维数组 赋值

    当类加载成功后,添加 分类 list有值 ,走的是 1+多个的方式

    当在加一个分类是。 rew 是一个数组 【本类+第一个分类】 ,走 hasArray 方法,即 本类+分类的list ,走 多对多流程

    流程如下:

    分类的加载流程如下图所示:

    类和分类的懒加载/非懒加载:

    根据懒加载和非懒加载的状态,类和分类有没有懒加载可以分为以下几种情况:

    类和分类都实现了 load 方法

    分类实现了load方法,类没有实现load方法

    类实现了load方法,分类没有实现

    类和分类都没有实现load方法

    类和分类的加载流程

    读取类的名称和地址信息 readClass

    根据名称和地址信息,从 Math_O 加载类的属性,方法,协议,到内存中 realizeClassWithoutSwift

    realizeClassWithoutSwift 里面有两个东西:

  • 序列化类的方法,协议等信息
  • 添加类/分类的数据信息 attachCategories
  • 综上所述, 类从Mach-O加载到内存 的流程图如下所示

    此图参考《 类的加载

    分类:
    阅读