美文网首页
类的加载(上)

类的加载(上)

作者: 北京_小海 | 来源:发表于2020-10-16 18:50 被阅读0次

    上一篇我们着重讲了dyld和objc的关联 今天继续深入了解后续的流程

    上篇我们也了解到了_read_images的流程 首先继续深入了解map_images中的_read_images

    _read_images

    那我们要分析类的加载。就断点调试一波。找到关于类的方法

    根据注释我们注意这块是探索类,于是我断点调试了一下 cls 是地址 而newcls就变成了名字

    那么readClass里面我们去看个究竟~~~

    readClass分析

    我们从上面得出的结论是。readClass 把 cls和类名关联起来的~。那么我们继续分析

    miss和fixup什么的都不是重点 分析重点感觉addNamedClass和addClassTableEntry很有用 进行一波调试准备

    先筛选出我自己创建的类名 

    下面进行调试

    果然就是addNamedClass,给了cls名字

    跟进发现是NXMapInsert进行了一些操作~~有兴趣的童鞋可以深入研究下~~

    addClassTableEntry


    显而易见就是将类添加到表中~~

    类的加载过程(ro,rw,rwe的赋值)在什么时候进行的?我们继续探索~~

    懒加载与非懒加载

    懒加载:推迟到 第一次消息发送的时候~

    非懒加载:当map_images的时候,加载所有类数据的时候就加载

    懒加载和非懒加载的区别标志:当前类是否实现load方法(大家都知道load在main函数之前,其实就是你进入main之前我就加载你了)

     非懒加载分析

    我们调试的时候没有走到这里,说明我们没有的类实现load,

    那我们加上load方法试试

    果然进来了 实现load方法就属于非懒加载~~

    我们通过断点调试,发现他走的是 realizeClassWithoutSwift(cls, nil);。那么我们研究下这个方法

    realizeClassWithoutSwift

    我们的类先实现一些方法 并且筛选下我们的类便于调试

    代码比较多我就讲重点~~ cls如果实现就返回  之后就是设置rw ro

    递归 父类元类 走本方法 

    继承连与isa走向关联了

    最后这个分类相关方法

    懒加载分析

    我们把load方法去掉 看下bt和堆栈

    最终也会走 realizeClassWithoutSwift,不过他是通过方法查找的时候实现类。

    * 1: 懒加载类情况 数据加载推迟到第⼀次消息的时候

    lookUpImpOrForward

    realizeClassMaybeSwiftMaybeRelock

    realizeClassWithoutSwift

    methodizeClass

    调用堆栈: [LGPerson alloc] --> objc_alloc -->callAlloc --> _objc_msgSend_uncached -->lookUpImpOrForward -->initializeAndLeaveLocked-->initializeAndMaybeRelock-->realizeClassMaybeSwiftAndUnlock-->realizeClassMaybeSwiftMaybeRelock --> realizeClassWithoutSwift

    * 2: ⾮懒加载类情况 map_images的时候 加载所有类数据

    _getObjc2NonlazyClassList 

    readClass

    realizeClassWithoutSwift

    methodizeClass

    调用堆栈:_dyld_start --> _objc_init --> _dyld_objc_notify_register --> dyld::registerObjcNotifiers --> dyld::notityBatchPartial --> map_images -->map_images_nolock --> _read_images --> realizeClassWithoutSwift

    分类

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

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

    分类的加载

    在上面,我们已经通过 methodizeClass中找到了,分类的加载 attachToClass

    断点调试发现并没有走下面的if~~

    加上load方法就进去了

    看下重点代码

    如果存在,就直接获取,如果不存在,就开辟创建

    rwe是在分类的添加的时候才进行处理,所以在这个时候才会进行初始化。

    在经过一翻查询后,可以得到分类的添加处理在addMethod、addPro、addprotocol的时候都会进行处理。未完待续~~~

    相关文章

      网友评论

          本文标题:类的加载(上)

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