APP启动过程

启动过程

一. 加载main函数,应用创建的第一个实例就是main函数中的UIApplicationMain实例

int main(int argc, char * argv[]) {
    
    @autoreleasepool {
        
        return UIApplicationMain(argc, argv, @"EOCApplication", NSStringFromClass([EOCAppDelegate class]));
        
    }
}

前两个参数:argc是命令行总的参数个数,argv是参数的数组,值得一提的是argv中第一个参数为app的路径+全名。

默认的第三个参数是nil,但是它实际传的是UIApplication,我们也可以写一个继承自UIApplication的类* EOCApplication来代替它。
NSStringFromClass方法是为了更安全,确保它是一个字符串类型,里面的类默认的是
AppDelegate,但是我们也可以写一个继承自UIResponder的类来代替,如果没有响应事件,也可以只是继承自NSObject。但是都必须遵循UIApplicationDelegate*代理方法,并且在.h文件中声明一个window属性,因为只有声明了window属性,控制器才能够加载window。

@interface EOCAppDelegate : NSObject<UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

声明window属性,必须头文件要引入UIKit框架

二. 在main函数中创建Application对象 创建Application的Delegate对象。

三. 开启主事件循环runloop,AppDelegate代理对象开始监听系统事件(这是一个死循环,APP就是在这个循环里面监听并处理事件)。

四. 启动完毕会调用 didFinishLaunching方法,并在这个方法中创建并显示UIWindow

  • 设置UIWindow的根控制器是谁
  • 如果有storyboard,会根据info.plist中找到应用程序的入口storyboard并加载箭头所指的控制器
  • 显示窗口
runloop

runloop源码地址:地址
内部原理大概如下:

runloop  while (1){
    
    model while(1){
        切换的时候
        跳出去了
    }
}
隐藏状态栏

其中根视图最好固定,需要到登陆界面就跳转过去 在keyWindow上进行操作

windowLevel
UIWindowLevelAlert > UIWindowLevelStatusBar > UIWindowLevelNormal

其中隐藏状态栏,可以在didFinishLaunchingWithOptions方法中将keyWindow的层级设置为最高,因为状态栏其实也是一个window,这样就会覆盖掉状态栏,但是这样在整个APP里面都覆盖了

self.window.windowLevel = UIWindowLevelAlert;

当然也还有其他的方法隐藏状态栏

关于AppDelegate中的一些调用顺序
应用从前台进入后台
  • applicationWillResignActive
  • applicationDidEnterBackground

先失去焦点,再进入后台

从后台进入前台
  • applicationWillEnterForeground
  • applicationWillResignActive

先进入前台,再获取焦点。但是如果在进入前台的时候,你进行了大量的操作,比如说请求数据之类的,可能会引起卡顿,所以这个时候,可以另外开辟一个线程来做这些操作

关于项目拆分

可以使用分类或者类工厂来进行拆分

分类

为了使AppDelegate代理方法中的代码,更加方便阅读,可以按照业务创建几个AppDelegate的分类,然后再在主要的AppDelegate中进行调用。


类工厂
关于项目添加文件夹的时候

group :一般只在你的工程中是文件夹的形式,但是在本地的目录中还是以散乱的形式放在一起的,除非你是从外部以group的形式引用进来的。
folder: 只能作为资源,整个引用进项目,不能编译代码,也就是说,以folder形式引用进来的文件,不能被放在complie sources列表里面

启动时间

时间分为两个部分 T1(main前) + T2(main后), {T1:系统环境布局时间:创建进程,加载解析可执行文件(库加载,堆栈环境配置等等), T2:从main到第一个界面显示时间}
1、 库加载越多,启动越慢
2、 Objc类越多,越慢
3、 静态对象全局对象越多,启动越慢
4、 Objc的 +load越多,启动越慢
更能把控的:load 和 T2时间上进行优化 (前面三点随着项目越大,库和类就越多,我们不太好进行优化)

每个控制器的load加载在main函数运行之前,并且按照项目中文件配置先后顺序加载:


.m文件资源的先后顺序.png

运行结果.png

我们尽可能少用控制器的load方法,已经在里面少做耗时的操作,如果有一些操作,可以用initialize方法代替

T2时间即是:从didFinishLaunchingWithOptions这个方法到显示出第一个界面的时间。所以我们尽可能在这个方法中少做操作,如果有耗时的操作移到子线程,也就是第一个界面出来之后再执行,可以做到优化

参考文章:
iOS 从main函数开始
iOS:App启动过程详解
iOS APP启动时所有方法的调用顺序分析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 文章中的观点主要通过阅读苹果官方文档和代码调试结果得出,如有偏差或者遗漏的地方,欢迎留言指出。 这张图来自于...
    木小土阅读 1,317评论 2 2
  • 程序入口点 当iOS app启动时,系统会根据app bundle中的 Info.plist 文件中的 Execu...
    木板钉钉阅读 3,475评论 2 9
  • 当用户点击应用图标之后,应用就开始启动。应用启动完成后,就会展示一系列的视图,和用户进行各种各样的交互(如滑动、点...
    Pandakingli阅读 739评论 0 1
  • 买菜有时候也算得上一门学问吧,生活中的小学问。 对于像我妈这一年轻的人,买菜可以经验丰富。哪个市场的菜便宜又新鲜,...
    34_亦寞落阅读 213评论 0 0
  • 十一号晚上十一点半,你登上来这里的飞机,我刚下班推开了家门。 十二号早上一点钟,你坐上机场大巴,我在沙发上睡的迷迷...
    叶泱曲庸阅读 544评论 4 6