###一.UIApplicationMain函数 iOS程序启动的时候首先会进入main.m文件的UIApplicationMain函数,关于UIApplicationMain函数可以按住option查看官方介绍
Summary:
Creates the application object and the application delegate and sets up the event cycle.
Declaration:
int UIApplicationMain(int argc, char * _Nullable *argv, NSString *principalClassName, NSString *delegateClassName);
Discussion:
This function instantiates the application object from the principal class and instantiates the delegate (if any) from the given class and sets the delegate for the application. It also sets up the main event loop, including the application’s run loop, and begins processing events. If the application’s Info.plist file specifies a main nib file to be loaded, by including the NSMainNibFile key and a valid nib file name for the value, this function loads that nib file.
Despite the declared return type, this function never returns. For more information on how this function behaves, see “Expected App Behaviors” in App Programming Guide for iOS.
Parameters:
argc:
The count of arguments in argv; this usually is the corresponding parameter to main.
argv:
A variable list of arguments; this usually is the corresponding parameter to main.
principalClassName:
The name of the UIApplication class or subclass. If you specify nil, UIApplication is assumed.
delegateClassName:
The name of the class from which the application delegate is instantiated. If principalClassName designates a subclass of UIApplication, you may designate the subclass as the delegate; the subclass instance receives the application-delegate messages. Specify nil if you load the delegate object from your application’s main nib file.
Returns:
Even though an integer return type is specified, this function never returns. When users exits an iOS app by pressing the Home button, the application moves to the background.
通过官方介绍可以看出这个函数做了三件事
- 创建application对象
- 创建application delegate代理
- 开启事件循环(主运行循环,死循环,先进先出,保证应用程序不退出)
#####1.参数介绍
int UIApplicationMain(int argc, char * _Nullable *argv, NSString *principalClassName, NSString *delegateClassName);
此函数有四个参数,如下: **argc:**系统或者用户传入的参数 **argv:**系统或用户传入的实际参数 **principalClassName:**指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值 **delegateClassName:**指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议 **Returns:**虽然有返回值,但是永远不会返回
#####2.程序启动流程
- UIApplicationMain函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性
- 接着会建立应用程序的Main Runloop(事件循环),进行事件的处理
- 去加载info.plist.(判断info.plist中的NSMainNibFile属性有没有值,如果有,加载Main.storyBoard)
- 应用程序启动完毕,通知代理应用程序启动完毕 (首先会在程序完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法), 之后在这个方法里面创建Window设置根控制器显示窗口等
- 如何优化appDelegate里面的代码? 给appDelegate添加分类,在不同的分类中写不同的代码
- 如何优化启动时间? 启动时间分两部分 T1:main之前(系统环境布局,创建进程,加载解析可执行文件(库加载,堆栈环境配置)) T2:从main到第一个界面显示时间
- 库加载越多,启动越慢
- Objc类越多,启动越慢
- 静态对象全局对象越多,启动越慢
- Objc的+load越多,启动越慢
其他的不好控制,可以在+load和T2时间进行优化 方法1: +load方法换成+initialize方法(+load方法是在UIApplicationMain函数之前调用的) 方法2: 耗时的操作不要放到application:didFinishLaunchingWithOptions方法, 放到子线程来执行
###二.UIApplication对象 一.简单介绍
- UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序
- 每一个应用都有自己的UIApplication对象,而且是单例的,如果试图在程序中新建一个UIApplication对象,那么将报错提示
- 通过[UIApplication sharedApplication]可以获得这个单例对象
- 一个iOS程序启动后创建的第一个对象就是UIApplication对象,且只有一个(通过代码获取两个UIApplication对象,打印地址可以看出地址是相同的
- 利用UIApplication对象,能进行一些应用级别的操作
二.常用功能 1 设置提醒 2 设置联网状态 3 设置状态栏 4 打开URL
- 设置提醒
@property(nonatomic) NSInteger applicationIconBadgeNumber;
- 设置联网指示器
@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
- 设置状态栏
从iOS7开始,系统提供了2种管理状态栏的方式
- 通过UIViewController管理(每一个UIViewController都可以拥有自己不同的状态栏 在iOS7中,默认情况下,状态栏都是由UIViewController管理的,UIViewController实现下列方法就可以轻松管理状态栏的可见性和样式
- (UIStatusBarStyle)preferredStatusBarStyle; //状态栏的样式
- (BOOL)prefersStatusBarHidden;//状态栏的可见性
#pragma mark-设置状态栏的样式
-(UIStatusBarStyle)preferredStatusBarStyle {
//设置为白色
//return UIStatusBarStyleLightContent;
//默认为黑色
return UIStatusBarStyleDefault;
}
#pragma mark-设置状态栏是否隐藏(否)
-(BOOL)prefersStatusBarHidden {
return NO;
}
- 通过UIApplication管理(一个应用程序的状态栏都由它统一管理)
如果想利用UIApplication来管理状态栏,首先得修改Info.plist的设置,如下👇
//通过sharedApplication获取该程序的UIApplication对象
UIApplication *app=[UIApplication sharedApplication];
//设置提醒
app.applicationIconBadgeNumber=123;
//设置指示器的联网提示
app.networkActivityIndicatorVisible=YES;
//设置状态栏的样式
app.statusBarStyle=UIStatusBarStyleDefault;//默认(黑色)
//设置为白色+动画效果
[app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
//设置状态栏是否隐藏
app.statusBarHidden=YES;
//设置状态栏是否隐藏+动画效果
[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
- 打开URL
UIApplication有个功能十分强大的openURL:方法
- (BOOL)openURL:(NSURL*)url;
openURL:方法的部分功能有:
UIApplication *app = [UIApplicationsharedApplication];
[app openURL:[NSURLURLWithString:@"tel://10086"]]; //打电话
[app openURL:[NSURLURLWithString:@"sms://10086"]];//发短信
[app openURL:[NSURLURLWithString:@"mailto://12345@qq.com"]];//发邮件
[app openURL:[NSURLURLWithString:@"http://ios.itcast.cn"]];//打开一个网页资源或者其他app
URL补充: URL:统一资源定位符,用来唯一的表示一个资源。 URL格式:协议头://主机地址/资源路径 网络资源:http/ ftp等 表示百度上一张图片的地址 www.baidu.com/images/2014… 本地资源:file:///users/apple/desktop/abc.png(主机地址省略)
###三.UIApplicationDelegate代理
所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止。 还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件。 每次新建完项目,都有个带有“AppDelegate”字眼的类,它就是UIApplication的代理
AppDelegate的一些代理方法如下👇
//当应用程序启动完毕的时候就会调用(系统自动调用)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"didFinishLaunchingWithOptions");
return YES;
}
// 即将失去活动状态的时候调用(失去焦点, 不可交互)
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(@"ResignActive");
}
// 重新获取焦点(能够和用户交互)
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(@"BecomeActive");
}
// 应用程序进入后台的时候调用
// 一般在该方法中保存应用程序的数据, 以及状态
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"Background");
}
// 应用程序即将进入前台的时候调用
// 一般在该方法中恢复应用程序的数据,以及状态
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"Foreground");
}
// 应用程序即将被销毁的时候会调用该方法
// 注意:如果应用程序处于挂起状态的时候无法调用该方法
- (void)applicationWillTerminate:(UIApplication *)application
{
}
// 应用程序接收到内存警告的时候就会调用
// 一般在该方法中释放掉不需要的内存
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
NSLog(@"MemoryWarning");
}