AppDelegate
iOS13之前,
AppDelegate
的职责是:全权处理App
生命周期和UI生命周期
iOS13之后,AppDelegate
的职责是:处理App
生命周期和SceneDelegate
生命周期
- 启动过程
main
函数 -> 自动释放池 ->UIApplicationMain
(永不返回,保证程序不会被销毁)-> 创建应用程序对象UIApplication
->创建应用程序的代理对象AppDelegate
->IOS13
之前,将AppDelegate
的window
实例化,设置为keyWindow
主窗口 -> 加载配置文件指定的storyboard
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
appDelegateClassName = NSStringFromClass([AppDelegate class]);
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
UIApplicationMain(argc, argv, nil, appDelegateClassName)
第3个参数nil:相当于应用程序类字符串@"UIApplication"创建一个应用程序对象
第4个参数:创建应用程序代理对象,将其设置为应用程序对象的代理
IOS13之前
NotRunning
(未运行):程序未运行Inactive
(未激活):程序在前台运行,但没有接收到事件。在没有事件处理情况下程序通常停留在这个状态。Active
( 激活 ): 程序在前台运行而且接收到了事件。这也是前台的一个正常的模式。Backgroud
( 后台 ):程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended
)。有的程序经过特殊的请求后可以长期处于Backgroud
状态。Suspended
( 挂起 ): 程序在后台但是却不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
func application(_:willFinishLaunchingWithOptions:)
// app即将初始化
func application(_:didFinishLaunchingWithOptions:)
// app初始化,应用程序加载完毕,可以加自定义操作
func applicationDidBecomeActive(UIApplication)
// app已经被激活,回到前台
func applicationWillResignActive(UIApplication)
// app即将被挂起,用于暂停app的操作,例如游戏中断
func applicationDidEnterBackground(UIApplication)
// app已经进入后台(挂起一段时间后进入后台),释放资源,保存数据,去掉定时器,保存app应用信息,防止被杀死没保存数据
func applicationWillEnterForeground(UIApplication)
// app即将回到前台,恢复操作
func applicationWillTerminate(UIApplication)
// app即将被杀死,销毁
func applicationDidReceiveMemoryWarning(UIApplication)
// app收到内存警告,需要释放内存,不然要被杀死
小技巧
- 虚拟机模拟内存警告::
Hardware
->Simulate Memory Warning
- 真机:调用私有
API
->[[UIApplication sharedApplication] performSelector:@(_performMemoryWarning)]
IOS13之后
SceneDelegate
sceneWillResignActive()//场景即将进入后台
sceneDidDisconnect()//场景进入后台,但未丢弃
sceneWillEnterForeground()//场景即将进入前台
ceneDidEnterBackground()//场景已经进入前台
sceneDidBecomeActive()//场景已回到前台,重新启动已暂停或新开始的任务
加载自定义控制器
- 将
viewControler
和Main.stroyboard
文件删除 - 将配置文件
info.plist
的Main.stroyboard
删除 - 在应用加载完毕代理方法里面创建窗口,指定大小
- 创建控制器,设置为窗口的根控制器
- 需要将这个
window
设置keyWindow
,并且可见
self.window = [[UIWindow alloc]initWithFrame: [UIScreen mainScreen].bounds];
UIViewController *viewController = [[UIViewController alloc]init];
//根控制器
self.window.rootViewController = viewController;
//keyWindow并可见
[self.window makeKeyAndVisible];
ios13
之后,写在SceneDelegate
里面
self.window = [[UIWindow alloc] initWithWindowScene:(UIWindowScene*)scene];
self.window.rootViewController = [[UIViewController alloc]init];
[self.window makeKeyAndVisible];
注意事项
UIWindow
默认隐藏的- 控制器的
view
是懒加载的,self.view
就去加载控制器的view
三种加载控制器的方式
- 方法一:纯代码如上
- 方法二:
storyboard
根据storyboard
拿到controller
//方法二storyboard
self.window = [[UIWindow alloc]initWithFrame: [UIScreen mainScreen].bounds];
//加载storyboard文件
UIStoryboard *SB = [UIStoryboard storyboardWithName:@"JJStoryboard" bundle:nil];
//当sb文件只有一个时,可以直接取出其控制器,
//当sb文件里面有多个,可以根据其identity属性取出
UIViewController *VC1 = [SB instantiateInitialViewController];
UIViewController *VC2 = [SB instantiateViewControllerWithIdentifier:@"identity"];
//设置控制器为VC1或者VC2
self.window.rootViewController = VC1;//VC2
//keyWindow并可见
[self.window makeKeyAndVisible];
- 方法三:
xib
创建并设置自定义控制器类
修改xib
的fileOwner
,将fileOwner
的view
连线到xib
内view
self.window = [[UIWindow alloc]initWithFrame: [UIScreen mainScreen].bounds];
xibViewController *xibC1 = [[xibViewController alloc]initWithNibName:@"xib的名称" bundle:nil];
//名称xib和controller相近时(少了controller),或者一致时,可以直接init
xibViewController *xibC2 = [[xibViewController alloc]init];
self.window.rootViewController = xibC1;//xibC2
//keyWindow并可见
[self.window makeKeyAndVisible];
IOS13以下打开黑屏问题
在AppDelegate.h
中添加
@property (strong,nonatomic) UIWindow *window; //解决低版本黑屏问题