iOS App冷启动过程

150 阅读4分钟
  1. 系统层面启动过程

   - 加载dyld(动态链接器)

     - 当用户点击iOS应用图标时,系统首先会加载dyld(the dynamic linker)。dyld负责加载应用的可执行文件以及与之相关的动态库。它会在系统规定的一些路径下查找这些文件,例如/usr/lib/System/Library/Frameworks等路径下的库文件。dyld的加载过程是系统级别的操作,这个过程相对复杂,它需要解析应用程序的依赖关系,确定需要加载的库以及这些库的加载顺序。

   - 加载可执行文件

     - 一旦dyld完成自身的启动,它就会开始加载应用的可执行文件。这个可执行文件包含了应用的代码和数据,例如所有的类、方法、全局变量等信息。在加载过程中,系统会对可执行文件进行内存映射,将其加载到进程的虚拟内存空间中。这个过程涉及到权限设置,例如代码段通常被设置为只读权限,数据段则根据数据的性质(如常量数据和可变数据)设置不同的权限。

   - 动态库链接

     - 在加载可执行文件后,dyld会开始链接动态库。iOS应用通常会依赖许多系统提供的动态库(如UIKitFoundation等)和第三方动态库。dyld会将这些动态库加载到内存中,并将应用可执行文件中的符号(如函数调用、类引用等)与动态库中的实际定义进行链接。这个过程确保了应用在运行时能够正确地调用库中的函数和访问类等资源。

  1. 应用自身初始化过程

   - 执行 +load方法

     - 在动态库链接完成后,系统会开始执行应用中所有类和分类(Category)的+load方法。+load方法是在类或分类被加载到内存时就会被调用的方法,且只会调用一次。这个方法通常用于一些必须在类加载时就执行的操作,例如注册全局的通知观察者、加载一些特定的资源等。不过,由于+load方法的执行顺序是按照文件的编译顺序来确定的,可能会导致一些不可预期的问题,所以在使用时需要谨慎。

   - 执行main函数

     - 接着就是执行应用的main函数。main函数是应用程序的入口点,在main函数中,通常会调用UIKitUIApplicationMain函数(对于基于UIKit的应用)。UIApplicationMain函数会创建应用的UIApplication对象和应用的代理(AppDelegate)对象,这两个对象在整个应用的生命周期管理和事件处理中起着关键作用。

   - AppDelegate初始化与应用启动流程设置

     - 在UIApplicationMain函数创建AppDelegate对象后,会开始执行AppDelegate的一些初始化方法。首先是application:didFinishLaunchingWithOptions:方法,这个方法是应用启动过程中最重要的方法之一。在这个方法中,开发者会进行一系列的初始化操作,例如设置应用的初始窗口(window)、根视图控制器(rootViewController),以及进行一些数据初始化、网络请求等操作。这些操作完成后,应用的主窗口和初始视图就会被显示出来,用户就可以开始与应用进行交互了。

  1. 视图控制器加载与显示过程(以UIKit为例)

   - 创建根视图控制器

     - 在AppDelegateapplication:didFinishLaunchingWithOptions:方法中,当设置了根视图控制器(rootViewController)后,系统会开始创建根视图控制器。这个过程包括加载视图控制器相关的视图文件(如果是通过故事板或者xib文件创建的视图)或者调用视图控制器的loadView方法(如果是纯代码创建的视图)。在这个过程中,会涉及到视图的初始化、布局等操作。

   - 视图加载与布局调整

     - 一旦根视图控制器的视图被加载,系统会进行视图的布局调整。这包括根据视图的约束(Constraints)或者自动布局(Auto - Layout)规则来确定视图的大小和位置。如果视图之间存在复杂的布局关系,例如嵌套视图、多个视图之间的对齐等,系统会按照布局规则逐步计算每个视图的最终位置和大小。这个过程可能会涉及到多次的布局计算和调整,直到所有视图的布局都满足要求。

   - 视图显示给用户

     - 最后,当视图的布局调整完成后,根视图控制器的视图会被添加到应用的主窗口(window)中,并显示给用户。这个过程标志着应用的冷启动过程基本完成,用户可以开始看到应用的界面并进行操作。在后续的操作中,根据用户的交互行为(如点击按钮、滑动屏幕等),系统会不断地加载和显示新的视图控制器,或者更新现有视图控制器的视图内容。