要想说清楚 iOS 的程序启动原理,首先必须了解一个类叫 UIApplication,下面请看 UIApplication 的作用
UIApplication
UIApplication 对象是一个单例对象。
有很多作用:
打开网页、打电话
UIApplication 有个功能十分强大的 openURL: 方法
1 | - (BOOL)openURL:(NSURL*)url; |
openURL:方法的部分功能有
打电话
1 | UIApplication *app = [UIApplication sharedApplication]; |
发短信
1 | [app openURL:[NSURL URLWithString:@"sms://10086"]]; |
发邮件
1 | [app openURL:[NSURL URLWithString:@"mailto://12345@qq.com"]]; |
打开一个网页资源
1 | [app openURL:[NSURL URLWithString:@"http://ios.itcast.cn"]]; |
打开其他app程序…
隐藏状态栏
在iOS7以后,状态栏默认由控制器决定(但是控制器不能搞动画)
1 | // 隐藏状态栏 |
设置提醒数字
1 | - (void)application |
UIApplicationDelegate
1 |
|
程序启动原理
在了解了 UIApplication 之后,就要深入 iOS 在程序启动初期到底做了些什么。
通过对 UIApplication 的了解,我们发现 UIApplication 其实是用来处理应用级别的事件的类型。
下图比较清晰的展示了 iOS 程序启动后执行代码的步骤
进入 main 函数,执行 UIApplicationMain
- UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))
- 参数:
argc、argv:直接传递给 UIApplicationMain 进行相关处理即可
principalClassName:指定应用程序类名(app的象征),该类必须是 UIApplication (或子类)。如果为 nil ,则用UIApplication 类作为默认值
delegateClassName:指定应用程序的代理类,该类必须遵守 UIApplicationDelegate 协议
- 参数:
- UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))
UIApplicationMain 函数会根据 principalClassName 创建 UIApplication 对象,根据 delegateClassName 创建一个 delegate 对象,并将该 delegate 对象赋值给 UIApplication 对象中的 delegate 属性
接着会建立应用程序的 MainRunloop(事件循环),进行事件的处理(首先会在程序完毕后调用 delegate 对象的application:didFinishLaunchingWithOptions:方法),确保程序一直在运行,了解什么是 RunLoop运行循环
加载 info.plist 如果 info.plist 中指定 main 就会加载 main 所以我们才能看见 mian.storyboard 的界面,加载完后,程序启动完成
程序正常退出时 UIApplicationMain 函数才返回
applicationState 说明
开始运行:
1 | - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions |
按home回到主界面:
1 | - (void)applicationWillResignActive:(UIApplication *)application |
从home唤起应用:
1 | - (void)applicationWillEnterForeground:(UIApplication *)application |
再次按home回到主界面:
1 | - (void)applicationWillResignActive:(UIApplication *)application |
干掉应用:
1 | - (void)applicationWillTerminate:(UIApplication *)application; |
需要注意的两点:
[[UIApplication sharedApplication] openURL:… ]此方法会和“按home回到主界面”的效果一样。较特殊的是拨打电话的时候,应用内拨打电话首先会弹出一个提示框,这时 applicationWillResignActive,确定拨打之后,调用 applicationDidEnterBackground,拨打完成后会顺序执行applicationWillEnterForeground,applicationDidBecomeActive
下拉通知面板和上拉设置面板,都只会回调 applicationWillResignActive 与 applicationDidBecomeActive。
总结一下就是只有进入过后台才能进入前台。看不见了才是进入后台。只要看得见都要激活