UIApplication对象是应用程序的象征,每一个应用程序都有自己的UIApplication对象,而且是单例的,通过[UIApplication sharedApplication]可以获得这个单例对象,一个iOS程序启动后创建的第一个对象就是UIApplication对象,通过它可以进行一些应用级别的操作(如打电话发短信发邮件,控制状态栏,联网状态,app未读提醒框,打开网页等)。
// @property(nonatomic) NSInteger applicationIconBadgeNumber; // set to 0 to hide. default is 0. In iOS 8.0 and later, your application must register for user notifications using -[UIApplication registerUserNotificationSettings:] // before being able to set the icon badge.//设置appIcon的提醒数字 iOS8.0之后必须注册用户通知才能使用app.applicationIconBadgeNumber = 10; //创建用户通知UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; //注册用户通知[app registerUserNotificationSettings:settings];//打开网页NSURL *url = [NSURL URLWithString:@"www.oschina.net"];[app openURL:url];//设置联网状态app.networkActivityIndicatorVisible = YES;//设置状态栏(用这种方法的前提是在info.plist文件中设置View controller-based status bar appearance的值为NO,也就是将状态栏交给UIApplication来管理类,iOS7之后默认是将状态栏交给ViewController管理的)[app setStatusBarHidden:YES];//还可以设置动画[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];//如果不设置info.plist中的值,就用下面的方法- (BOOL)prefersStatusBarHidden { return YES;}
当app收到干扰时,UIApplication会通知它的delegate去处理这些系统事件。UIApplication的delegate可处理的事件包括:应用程序的生命周期事件,系统事件,内存警告等。
UIApplicationDelegate协议中的方法:
@implementation AppDelegate/** * app启动完成之后调用 * * @param application * @param launchOptions * * @return */- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES;}/** * app失去焦点时调用 * * @param application */- (void)applicationWillResignActive:(UIApplication *)application { // 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.}/** * app进入后台时调用 在该方法中保存数据 * * @param application */- (void)applicationDidEnterBackground:(UIApplication *)application { // 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.}/** * 当app进入前台时调用 * * @param application */- (void)applicationWillEnterForeground:(UIApplication *)application { // 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.}/** * 当app获取焦点时调用,可以与用户交互了 * * @param application */- (void)applicationDidBecomeActive:(UIApplication *)application { // 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.}/** * 当app被销毁时调用 * * @param application */- (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.}/** * 当程序收到内存警告时调用 * * @param application */- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { }@end
应用程序的启动原理:
main.m文件中创建了一个UIApplicationMain对象
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); }}
UIApplicationMain的底层实现
第三个参数nil也是UIApplication对象,第四个参数是AppDelegate对象(遵守UIApplicationDelegate协议)
所以main函数中创建的这个UIApplicationMain对象做了什么事呢?
1、根据principalClassName提供类名创建了UIApplication对象(反射)
2、创建UIApplicationDelegate对象,并让其成为UIApplication对象的代理
3、开启一个main event loop(主运行循环),处理事件
4、加载Info.plist文件,看是否指定了main.storyboard,如果设置了就去加载main.storyboard
官方文档对主运行循环的描述:
app启动时会加载main.storyboard,那么加载main.storyboard时做了哪些事呢?
创建窗口->加载main.storyboard并且加载main.storyboard指定的控制器->创建的控制器成为窗口的根控制器,让窗口显示出来
/** * app启动完成之后调用 * * @param application * @param launchOptions * * @return */- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //创建窗口(窗口不能被释放,否则不能显示) self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor orangeColor]; //创建窗口的根控制器 UIViewController *vc = [[UIViewController alloc]init]; vc.view.backgroundColor = [UIColor yellowColor]; //让控制器成为窗口的根控制器(设置根控制器后窗口就可以自动旋转了) self.window.rootViewController = vc; //显示窗口 [self.window makeKeyAndVisible]; return YES;}