当前位置: 首页 > news >正文

深入解析 iOS 应用启动过程:main() 函数前的四大步骤

深入解析 iOS 应用启动过程:main() 函数前的四大步骤

在这里插入图片描述

背景描述:使用 Objective-C 开发的 iOS 或者 MacOS 应用

在开发 iOS 应用时,我们通常会关注 main() 函数及其之后的执行逻辑,但在 main() 函数之前,系统已经为我们完成了许多重要的初始化工作。这些工作确保了我们的应用能够顺利启动和运行。本文将详细解析在 main() 函数执行前,iOS 系统所做的四大步骤。

步骤一:加载可执行文件

当我们启动一个 iOS 应用时,系统首先会加载应用的可执行文件。可执行文件是由多个目标文件(.o 文件)链接而成的。这一步骤确保应用的核心代码和数据已经加载到内存中,准备好供后续使用。

步骤二:加载动态链接库,进行 Rebase 和 Bind

在加载可执行文件之后,系统会加载应用依赖的所有动态链接库(动态库或框架)。这一步骤包括两个重要的操作:

  1. Rebase(指针重定位):调整动态库在内存中的基地址,以确保所有内存引用都是正确的。
  2. Bind(符号绑定):解析和绑定所有符号(函数和全局变量的地址),以便在运行时可以正确调用这些符号。

通过这一步骤,系统确保所有外部依赖都已正确加载,并且符号地址已经绑定好,为后续的代码执行做好准备。

步骤三:Objective-C 运行时的初始处理

接下来,Objective-C 运行时会进行一系列初始化处理,包括:

  1. 类的注册:注册所有的 Objective-C 类,使其在运行时可用。
  2. Category 注册:注册所有的 Category,确保它们的方法被正确添加到相应的类中。
  3. Selector 唯一性检查:确保每个 Selector 在应用中是唯一的,避免方法调用冲突。

这些初始化处理确保了 Objective-C 运行时环境的正确性和稳定性。

步骤四:初始化工作

最后一步是各种初始化工作,按照实际执行顺序,如下所述:

  1. 调用用 attribute((constructor)) 修饰的函数
    这些函数会在加载动态链接库并进行基本内存布局之后首先被调用。这些函数用于执行早期的初始化操作。

  2. 执行类和 Category 的 +load 方法
    接下来,Objective-C 运行时会执行所有类和 Category 的 +load 方法。+load 方法在类或 Category 被加载到运行时时调用,用于执行类级别的初始化操作。需要注意的是,+load 方法的调用顺序是按照类和 Category 的加载顺序,父类的 +load 方法会先于子类的 +load 方法执行。

  3. 初始化和创建全局变量
    最后,系统会初始化和创建全局变量。这包括全局 C++ 对象的构造函数调用和全局 Objective-C 对象的初始化。这些变量的初始化通常会在 +load 方法之后进行,因为全局变量的初始化可能依赖于类的加载和初始化。

通过上述四个步骤,iOS 系统为我们的应用创建了一个稳定的运行环境,使得应用可以顺利地从 main() 函数开始执行主逻辑。

总结

在这里插入图片描述

main() 函数执行之前,iOS 系统进行了许多关键的初始化工作。这些工作包括加载可执行文件和动态链接库、进行 Objective-C 运行时的初始处理,以及执行一系列初始化操作。这些步骤确保了应用在启动时拥有一个稳定和正确的运行环境。

理解这些初始化过程,不仅有助于我们更好地理解 iOS 应用的启动机制,还能帮助我们在开发过程中优化应用的启动性能。希望这篇文章能对你有所帮助,让你对 iOS 应用的启动过程有更深入的了解。

相关文章:

  • 【开发12年码农教你】Android端简单易用的SPI框架-——-SPA
  • Spring MVC拦截器、文件上传和全局异常处理
  • Ubuntu下FastDDS的源码编译和简单测试
  • C语言小例程
  • 自动驾驶仿真Carla -ACC功能测试
  • Centos7 Mysql8.3.0 安装地址
  • 数据分析的数学概念
  • GitHub Copilot 登录账号激活,已经在IntellJ IDEA使用
  • 鸿蒙 HarmonyOS NEXT星河版APP应用开发—上篇
  • C#循环语句总结
  • LLM功能应用的测试艺术:策略与实践
  • 一颗B+树可以存储多少数据?
  • 【大数据 复习】第11,12,13,14章
  • SSRF服务端请求伪造
  • STM32三种调试工具CMSIS-DAP、J-Link和ST-Link
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 【React系列】如何构建React应用程序
  • Fabric架构演变之路
  • Fastjson的基本使用方法大全
  • Java方法详解
  • JS 面试题总结
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • 从0到1:PostCSS 插件开发最佳实践
  • 从重复到重用
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 开源SQL-on-Hadoop系统一览
  • 老板让我十分钟上手nx-admin
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 阿里云服务器购买完整流程
  • # include “ “ 和 # include < >两者的区别
  • #### go map 底层结构 ####
  • #考研#计算机文化知识1(局域网及网络互联)
  • (PADS学习)第二章:原理图绘制 第一部分
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (六)vue-router+UI组件库
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十六)一篇文章学会Java的常用API
  • (数据结构)顺序表的定义
  • (万字长文)Spring的核心知识尽揽其中
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .CSS-hover 的解释
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net 使用ajax控件后如何调用前端脚本
  • .net对接阿里云CSB服务
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • @Transactional 竟也能解决分布式事务?
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [Android] Implementation vs API dependency
  • [Angular] 笔记 7:模块
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)
  • [CSS]浮动
  • [DAU-FI Net开源 | Dual Attention UNet+特征融合+Sobel和Canny等算子解决语义分割痛点]