iOS开发之APP的启动过程及生命周期相关

关于App启动及初始化相关的知识点了解。

系统启动过程

App启动

  • main -> UIApplicationMain -> 通知代理做事情
  • UIApplicationMain底层实现:
1
2
3
4
// principalClassName:描述UIApplication的类名字符串
// delegateClassName:描述UIApplication代理的类名字符串

int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

程序启动的完整过程

  • main函数
  • UIApplicationMain

    • 创建UIApplication对象
    • 创建UIApplication的delegate对象
  • delegate对象开始处理(监听)系统事件(判断有无storyboard)

  • A. 根据Info.plist获得最主要storyboard的文件名,加载最主要的storyboard(有storyboard)
    • 创建UIWindow
    • 创建和设置UIWindow的rootViewController
    • 显示窗口
  • B. 没有storyboard
    • 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法
    • application:didFinishLaunchingWithOptions:中创建UIWindow
    • 创建和设置UIWindow的rootViewController
    • 显示窗口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 在开发中通常在程序启动完成的时候手动创建窗口
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 1.创建窗口
// 让窗口显示:1.必须要有强引用2.窗口也是控件,是控件要想展示出来,必须设置尺寸
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

self.window.backgroundColor = [UIColor yellowColor];

// 2.创建控制器
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor greenColor];

// 2.1 设置窗口的根控制器,底层:1.就会把控制器的view添加到窗口上
// 2.给界面添加旋转功能
self.window.rootViewController = vc;
NSLog(@"%@",application.keyWindow);

// 3.显示窗口:称为主窗口,并且显示窗口
[self.window makeKeyAndVisible];
// 1. self.window.hidden = NO;
// 2. 称为应用程序的主窗口
NSLog(@"%@",application.keyWindow);

NSLog(@"%@",self.window);

return YES;
}

Application生命周期方法介绍

  • AppDelegate没有自己创建,系统会默认帮我们创建。
  • 处理应用程序的一些生命周期方法:以application开头
1
2
3
4
5
6
7
8
9
// 程序启动完成的时候调用
// __func__:表示当前的方法在哪个类里面调用
// -[AppDelegate application:didFinishLaunchingWithOptions:]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

NSLog(@"%s",__func__);
// Override point for customization after application launch.
return YES;
}
1
2
3
4
5
6
// 当应用程序失去焦点的时候调用
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"%s",__func__);
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
1
2
3
4
5
6
7
// 当应用程序进入后台的时候调用
// 保存一些数据
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"%s",__func__);
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
1
2
3
4
5
// 当应用程序进入进台的时候调用
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"%s",__func__);
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
1
2
3
4
5
6
// 当应用程序获取焦点的时候调用
// 当用户完全获取焦点的时候,才能跟界面交互
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"%s",__func__);
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
1
2
3
4
// 当应用程序关闭的时候调用
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
1
2
3
4
5
6
// 当程序接收到内存警告的时候调用
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
// 清空图片缓存
NSLog(@"%s",__func__);
}

类相关的

load

  • load方法会在加载类的时候就被调用,也就是ios应用启动的时候,就会加载所有的类,就会调用每个类的 + load 方法。

    initialize

  • initialize方法会在第一次初始化这个类之前被调用,我们用它来初始化静态变量。

LoadView

  • 什么时候调用:第一次使用控制器的view的时候调用
  • 作用:加载控制器的view
    • 注意:
    • 只要重写loadView,里面就不要调用 [super loadView]
    • 在loadView方法中,如果没有给控制器的view赋值,就不能获取控制器的view,否则会导致死循环
  • 一旦重写loadView方法,表示需要自己创建控制器的view

  • 在开发中loadView应用场景:

    • 一开始控制器就想要展示一张图片,就可以直接让控制器的view是UIImageView
    • UIWedView:展示网页,设置wenbView为控制器View
    • 重写LoadView,可以减少内存使用,直接帮你创建控制器最想要的view
  • [super loadView]:首先判断下有没有指定storyboard或者指定xib,如果指定了,就会帮你加载指定的控制器的view
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (void)loadView
{
// super -> UIViewController
// [super loadView];
// 创建控制器的view
// 只要当前控制器是根控制器,系统会自动设置控制器的view尺寸(但是不建议这么写,开发中直接指定为[UIScreen mainScreen].bounds)
UIView *vcView = [[UIView alloc] initWithFrame:CGRectZero];

vcView.backgroundColor = [UIColor redColor];

self.view = vcView;

}
// 系统启动会默认自动调用这个系统方法判断view是否为空 为空则会调用loadView方法
//- (UIView *)view
//{
// if (_view == nil) {
// [self loadView];
// }
// return _view;
//}
要不要鼓励一下😘