iOS 类的加载

一、 应用程序加载

  • 系统调用exec()会让我们的应用程序映射到新的地址空间
  • 然后通过dyld进行加载、链接、初始化主程序和应用程序所依赖的各种动态库
  • 最后在initializeMainExecutable犯法中经过一系列的初始化调用notifySingle函数,该函数会执行一个load_images的回调
  • 在doModInitFunctions函数内部调用attribute((contrustor))的C++函数
  • 在dyld返回主程序的入口函数,开始进入主程序的main函数
    在main函数执行过程中,其实dyld还会在流程中初始化libSystem,而libSystem又会去初始化libDispatch,在libDispatch初始化方法里边又会调用os_object_int, 在os_object_int内部就会调用objc_init,从而才会进入我呢相隔类的加载过程。这就是整个应用程序加载的大致过程

二、类的加载

应用程序相关的加载和编译在main函数之前,在read_image字段中进行镜像images读取
在read_images中找到关于类的信息

  • 关于非懒加载类
    Realize non-lazy classes (for +load methods and static instances)
    在自定义的类方法中,我们探究所定义的类加载到内存中,根据代码的执行,我们找到如下的方法:
static Class realizeClassWithoutSwift(Class cls, Class previously)

在中途通过mangleName筛选到我们当前的类

  • 通过macho文件里的data返回一个类的class_ro_t从而赋值到响应的ro中即cleanMemory
  • 判断是否为元类,通过第一步的ro数据,读取到rw
  • 如果非元类,即进行相应的数据从ro到rw中,通过re->set_ro(ro);操作完成
  • 完成相关类的继承链,从而为以后的方法查找以及后续的初始化埋下伏笔
此时的类还只是带地址的一个名字,并没有实现,但我们相关的ro和rw是有值的

通过以上方法我们知道了相关的类的信息,并且成功将数据映射到内存,包括ro和rw的赋值都在此时实现,所以在此去实现相关元类meta信息,从而进入到最后的methodizeClass(cls, previously);中
最后进入到attachToClass中,从而进行相关类的方法、协议的实现

  • 懒加载类
    在+load方法没有实现的时候,我们发现程序的执行和之前的流程不太一样,程序会先进入到底层的objc_msgSent,因为我们在创建
Person *per = [Person alloc];

程序底层会进行一次消息转发,从而进入到消息的查找从而进入到lookUpImpOrForward
进行程序实现的判断
之后进入到realizeClassMaybeSwiftAndLeaveLocked中,从而实现和非懒加载类一样执行realizeClassWithoutSwift和methodizeClass的流程,从而实现该类的信息

三、分类的加载

  • 3.1分类的概念和结构
    分类的内部结构
  • name:分类的名字
  • cls 分类的类
  • instance_methods: 实例方法
  • class_methods:类方法
  • protocols:协议列表
  • properties:属性列表
  • 3.2、分类加载到应用程序时机
    类加载执行methodizeClass(cls, previously);
    程序加载分裂的机制和时机
methodizeClass(cls, previously)

通过定位到我们的类,然就进行打印相关的列表
通过list,假如为无序时,我们进行相关排序操作

 method_list_t *list = ro->baseMethods();
    if (list) {
        prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
        if (rwe) rwe->methods.attachLists(&list, 1);
    }

通过这个方法去加载相关分类的属性,方法,协议等,实现分类,从而对内存中的rwe进行调用和开辟
通过以上的attachList方法,从而循环对分类的属性、协议、方法等操作具体实现

  • 判断要添加的数量是否为0,如果为0,则直接返回
  • 对ATTACH_BUFSIZ - ++mcount所有的方法进行倒序插入
  • 判断attachLists的list_array_tt二维数组有多一个一位数组
    如果是,说明多对多的关系
    通过realloc对容器进行重新分配,大小是原来的大小加上新增的大小
    通过memmove把原来的数据移动到尾部
    最后把新的数据拷贝到容器的起始位置,
  • 如果调用的attachLists的list_array_tt二位数组为空且新增控件大小数目为1,则直接取attachList的第一个list
  • 如果当前调用的attachLists的list_array_tt二位数组只有一个一位数组
    如果是,说明是一对多的关系
    通过realloc对容器进行重新分配,大小是原来的大小加上新增的大小
    因为原来只有一个一位数组,所以直接赋值到新array的最后一个位置
    最后把新的数据拷贝到容器的起始位置
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容