二十四、app加载流程(七)load_images

本文由快学吧个人写作,以任何形式转载请表明原文出处

一、资料准备

objc4-818.2

对应mac的版本是11.1。可根据自己的系统版本挑选可以进行调试的源码。

二、思路

  1. 从app的加载流程的第一章开始,就知道了app在启动的过程中会利用dyld这个动态链接器,将动态库与mach-o可执行文件进行链接,然后调用动态库的初始化函数,在第二章中知道了在最常用的libobjc动态库的初始化函数_objc_init中会有dyld的回调函数,将变成镜像的库映射到内存上,也就是map_images。
  2. 但是在_dyld_objc_notify_register这个回调函数中,还有两个函数没有探索,其中之一就是load_images,根据命名,可以知道是加载镜像。又好像和(+void)load方法有关。
  3. load方法比程序的main()函数还要早的调用,是否和load_images有关系?还有在上一章,分类的加载中,也发现了load_images的调用,所以load_images到底做了什么?

三、load_images源码

核心源码如下图中红框 :

(1). loadAllCategories,在上一章上上章说过了。主要是连接分类和类、类的rwe的开辟、已经将分类的数据贴入类的rwe。

(2). prepare_load_methods : 为load方法的正式调用做准备.

(3). call_load_methods : 调用所有的load方法。

四、prepare_load_methods源码

作用 : 为类和分类的load方法的调用做准备。

1. 总体逻辑

2. schedule_class_load

将类和类的load方法的IMP包装成一个对象,然后添加到一张表中,表存的是所有的需要加载load方法的类和类对应的load方法的IMP。

核心函数 : add_class_to_loadable_list

add_class_to_loadable_list源码 :

loadable_classes是存放loadable_class结构体的数组。

loadable_class,结构体类型,存放着类和类的load方法的IMP。

loadable_classes_usedloadable_classes的索引,int类型,是个全局静态变量,指的是已经存放了多少个loadable_class结构体对象。

loadable_classes_allocated是记录loadable_classes的大小,int类型,也是全局静态变量。

3. add_category_to_loadable_list

分类没有父类,也就不需要先对父类做处理。直接添加到分类的load方法列表中。逻辑和上面的类是一样的。

4. getLoadMethod和_category_getLoadMethod

逻辑是一样的,只说一个。重点就是 : 从类方法中获取load方法的IMP,因为load都是类方法。

5. 小结

  1. prepare_load_methods是将类和分类分别加入对应的存储load方法的列表中。

(1). 类是isa指向的元类的ro中拿到方法列表来获取load方法的IMP。

(2). 分类是从分类自己的结构体内部的classMethods获取load方法的IMP。

  1. 对于类 :

(1). 先处理父类的load方法,将父类先加入列表。然后再处理自己的。

(2). 加入的是loadable_classes表,表中存放的是结构体loadable_class,结构体的成员是Class和IMP。

(3). loadable_classes表的初始大小是16,每次扩容都是 : 原有大小 * 2 + 16。

  1. 对于分类 :

(1). 分类没有父类的概念,不需要处理父类,直接处理自己。

(2). 加入的是loadable_categories表,表中存放的是结构体loadable_category,结构体成员是Category和IMP。

(3). loadable_categories表的初始大小也是16,每次扩容也是 : 原有大小 * 2 + 16。

五、call_load_methods

作用 : 调用所有类的load列表中的load方法,调用所有分类的load列表中的load方法。

1. 总体逻辑

2. call_class_loads

类的方法调用的循环是在外部进行的循环,因为类是固定的只有1个,其他的类就是其他的类,不会和自己的load有什么关系。

load_method_t :

就是直接把IMP强转成了函数指针形式,这样就可以直接调用函数,不需要经过objc_msgSend这样的流程。

3. call_category_loads

思路和类的一样,唯一不一样的就是如果在这个过程中,如果有新的分类的load方法加入进来了,就会继续最外面的do...while循环,继续将新加入的load方法也调用。

六、总结

load_images做了三件事情 :

  1. 第一次进入的时候,会将分类和类关联,在类的内部开辟rwe,将分类的数据存储到类的rwe中。

  2. 调用类和分类的load方法前的准备工作。准备工作就是将类和分类的load方法以及对应的类和分类一一组合成一个结构体,然后分别加入类和分类的待加载load表中。

  3. 循环调用类和分类的load方法。类的load方法一定在分类之前调用,父类的load方法一定在子类前调用。

相关推荐
初级代码游戏14 小时前
iOS开发 SwiftUI 8:NavigationView 导航
ios·swiftui·swift
美狐美颜SDK开放平台16 小时前
跨平台开发实战:直播美颜sdk动态贴纸在 Android / iOS / HarmonyOS 的落地方案
android·ios·harmonyos·美颜sdk·直播美颜sdk·视频美颜sdk·美颜api
2501_9160088916 小时前
在不越狱前提下导出 iOS 应用文件的过程,访问应用沙盒目录,获取真实数据
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_9151063216 小时前
Android和IOS 移动应用App图标生成与使用 Assets.car生成
android·ios·小程序·https·uni-app·iphone·webview
2501_9159184117 小时前
Mac 抓包软件有哪些?Charles、mitmproxy、Wireshark和Sniffmaster哪个更合适
android·ios·小程序·https·uni-app·iphone·webview
2501_9151063217 小时前
iOS 抓包绕过 SSL 证书认证, HTTPS 暴力抓包、数据流分析
android·ios·小程序·https·uni-app·iphone·ssl
WeiAreYoung17 小时前
uni-app xcode 制作iOS Notification Service Extension 远程推送图文原生插件
ios·uni-app·xcode
2501_915921431 天前
iOS App 电耗管理 通过系统电池记录、Xcode Instruments 与克魔(KeyMob)组合使用
android·ios·小程序·https·uni-app·iphone·webview
且去填词1 天前
Context 详解:如何在微服务链路中传递取消信号与超时控制
ios·iphone
2501_915918411 天前
iOS App 测试方法,Xcode、TestFlight与克魔(KeyMob)等工具组合使用
android·macos·ios·小程序·uni-app·iphone·xcode