对于load方法的理解

发布时间 - 2025-07-17 00:00:00    点击率:

写在前面

关于load方法,我想大家应该已经有所了解。本文主要记录我在阅读ObjC源码时对load方法的新认知,因此文中会引用一些关键的ObjC源码。

+ load 是 Objective-C 中的一个方法,它会在整个文件被加载到运行时,并且在 main 函数调用之前由 ObjC 运行时调用。

本文将讨论关于+ load方法的三个问题:

  • load方法如何被调用。
  • load方法的调用顺序。
  • load方法的作用。

load方法是如何被调用的

我们可以清楚地看到,在+load方法之前被调用的方法包括:

1  call_class_loads()
2  call_load_methods
3  load_images
4  dyld::notifySingle(dyld_image_states, ImageLoader const*)
11 _dyld_start

(滑动显示更多)

dyld 是 the dynamic link editor 的缩写,它是苹果的动态链接器。

在我们启动App时,真正的加载过程是从exec()函数开始,系统会调用exec()函数创建进程并分配内存空间。随后会执行以下操作:

将App对应的可执行文件加载到内存。 将dyld加载到内存。dyld本身也是一个可执行程序。 dyld进行动态链接。dyld的工作内容包括:

dyld会找到可执行文件依赖的动态库。 接着dyld会将这些依赖的动态库加载到内存中。这是一个递归过程,因为依赖的动态库可能还会依赖其他动态库,所以dyld会递归每个动态库,直到所有依赖库都被加载完毕。 Rebase和Binding。每当有新的镜像加载之后,都会执行 load_images 方法进行回调,这里的回调是在整个运行时初始化时 _objc_init 注册的。

关于镜像的概念:

Mach-O 是 iOS 系统不同运行时期可执行文件的文件类型统称。

Mach-O 有三种文件类型:Executable、Dylib、Bundle。

Executable:app 的二进制主文件,同时也是 app extension 的二进制主文件。

Dylib:动态库。

Bundle:资源文件包。

镜像文件包含了上述的三种文件类型。

看到 load_images 方法

首先会调用 prepare_load_methods 对 load 方法的调用进行准备。

prepare_load_methods 方法的作用:

递归地加载当前类和未调用+ load 的父类进入加载列表,在将当前类加入加载列表之前,会先将父类加入待加载的列表,确保父类的 load 方法在子类之前调用。

然后开始调用 call_load_methods 方法。

其中 call_class_loads 会从一个待加载的类列表 loadable_classes 中寻找对应的类,然后找到 @selector(load) 的实现并执行。

这时就执行了 [XXX load] 方法。

load方法的调用顺序

当父类和子类都实现了 load 函数时,父类的 load 方法执行顺序优先于子类。 当一个类未实现 load 方法时,不会调用父类的 load 方法。 类中的 load 方法执行顺序优先于类别(Category)。 当多个类别(Category)都实现了 load 方法时,这些 load 方法都会执行,但执行顺序不确定(其执行顺序与类别在 Compile Sources 中出现的顺序一致)。 当有多个不同的类时,每个类的 load 执行顺序与其在 Compile Sources 出现的顺序一致。

load方法的作用

在 main 运行之前,load 方法就会被调用。

由于它的调用不是惰性的,且其只会在程序调用期间调用一次,最重要的是,如果在类与分类中都实现了 load 方法,它们都会被调用,不像其他在分类中实现的方法会被覆盖,这使得 load 方法成为了方法交换(Method Swizzling)的绝佳时机。

load方法注意事项:

load 调用时机较早,当 load 调用时,其他类可能尚未加载完成,运行环境不安全。不过在这个时间点,所有的 framework 都已经加载到了运行时中,所以调用 framework 中的方法是安全的。

load 方法是线程安全的,它使用了锁,我们应该避免在 load 方法中导致线程阻塞。


# 苹果  # ai  # 父类  # 子类  # 递归  # 线程  # ios  # 加载  # 多个  # 可执行文件  # 实现了  # 镜像  # 回调  # 类中  # 我想 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Android实现代码画虚线边框背景效果  高防服务器租用首荐平台,企业级优惠套餐快速部署  南京网站制作费用,南京远驱官方网站?  网站建设整体流程解析,建站其实很容易!  什么是javascript作用域_全局和局部作用域有什么区别?  IOS倒计时设置UIButton标题title的抖动问题  动图在线制作网站有哪些,滑动动图图集怎么做?  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  免费视频制作网站,更新又快又好的免费电影网站?  大型企业网站制作流程,做网站需要注册公司吗?  Laravel如何实现用户注册和登录?(Auth脚手架指南)  如何在IIS7中新建站点?详细步骤解析  如何用wdcp快速搭建高效网站?  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  高端云建站费用究竟需要多少预算?  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  Laravel怎么使用artisan命令缓存配置和视图  Java解压缩zip - 解压缩多个文件或文件夹实例  如何在服务器上配置二级域名建站?  Laravel怎么实现验证码(Captcha)功能  在Oracle关闭情况下如何修改spfile的参数  Laravel如何处理表单验证?(Requests代码示例)  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  ,南京靠谱的征婚网站?  EditPlus 正则表达式 实战(3)  iOS中将个别页面强制横屏其他页面竖屏  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  如何在万网利用已有域名快速建站?  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  如何在阿里云高效完成企业建站全流程?  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  Laravel Blade模板引擎语法_Laravel Blade布局继承用法  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  简单实现jsp分页  bootstrap日历插件datetimepicker使用方法  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  清除minerd进程的简单方法  Laravel如何创建自定义Facades?(详细步骤)  Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】  EditPlus中的正则表达式 实战(4)  如何在局域网内绑定自建网站域名?  开心动漫网站制作软件下载,十分开心动画为何停播?  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  如何在腾讯云服务器快速搭建个人网站?  在线制作视频的网站有哪些,电脑如何制作视频短片?  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法