一、前言
AppDelegate是作为Application的代理,不仅负责控制程序的生命周期,而且负责控制程序初始界面(初始StoryBoard)的显示,因此该代理类必须能够访问到初始界面的界面元素。
ios应用同web应用一样,启动过程中分别对应不同的生命周期活动。启动过程如下:
- 执行Main。
- 执行UIApplicationMain函数。
- 创建UIApplication对象,并设置UIApplicationMain对象的代理。UIApplication的第三个参数就是UIApplication的名称,如果指定为nil,它会默认为UIApplication;UIApplication的第四个参数为UIApplication的代理.。
- 开启一个主运行循环保证应用程序不退出。
- 加载 info.plist 配置文件。判断 info.plist 文件当中有没有Main storyboard file base name里面有没有指定storyboard文件,如果有就去加载 info.plist文件,如果没有,那么应用程序加载完毕。
其中,main函数就是应用程序的入口,main函数只是标记了一个自动释放池自动决定何时释放内存,并且返回了一个函数UIApplicationMain的执行结果。
换句话说,main函数直接调用UIApplicationMain执行,该UIApplicationMain接收的比较重要的最后一个参数为一个代理类的名字,UIApplicationMain据此参数来创建这个AppDelegate代理类,由AppDelegate通过对Application的控制来控制程序的生命周期。
那么什么是代理(又叫委托模式)?详参博文
苹果官方文档对代理模式的解释:
“Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.”
"代理是一种简单而强大的设计模式,在这种模式下,程序中的一个对象与另一个对象进行协调或响应。代理类持有委托方的一个引用并且在适当的时候向委托方发送一条消息,该消息通知委托方将有一个事件会被代理类处理或者代理类刚刚处理了一个事件。委托方可能会通过更新自身或其他对象的界面或状态来响应这条消息。在某些情况下他也能返回一个值来影响下一个即将被处理的事件。代理模式最主要的作用就是能够允许你对围绕同一个对象的多个对象进行更容易的自定义行为。"
下面逐一讲解各生命周期阶段对应的钩子函数。
二、didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
说明:当应用程序启动时执行,应用程序启动入口。只在应用程序启动时执行一次。application参数用来获取应用程序的状态、变量等,值得注意的是字典参数:(NSDictionary *)launchOptions,该参数存储程序启动的原因。
若用户直接启动,lauchOptions内无数据;
若由其他应用程序通过openURL:启动,则UIApplicationLaunchOptionsURLKey对应的对象为启动 URL(NSURL),UIApplicationLaunchOptionsSourceApplicationKey对应启动的源应用程序的 bundle ID (NSString);
若由本地通知启动,则UIApplicationLaunchOptionsLocalNotificationKey对应的是为启动应用程序的的本地通知对象(UILocalNotification);
若由远程通知启动,则UIApplicationLaunchOptionsRemoteNotificationKey对应的是启动应用程序的远程通知信息userInfo(NSDictionary);
其他key还有UIApplicationLaunchOptionsAnnotationKey,UIApplicationLaunchOptionsLocationKey,
UIApplicationLaunchOptionsNewsstandDownloadsKey。
如果要在启动时,做出一些区分,那就需要在下面的代码做处理。
比如:应用可以被某个其它应用调起(作为该应用的子应用),要实现单点登录,那就需要在启动代码的地方做出合理的验证,并跳过登录。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = [options objectForKey:UIApplicationLaunchOptionsURLKey];
if(url)
{
}
NSString *bundleId = [options objectForKey:UIApplicationLaunchOptionsSourceApplicationKey];
if(bundleId)
{
}
UILocalNotification * localNotify = [options objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if(localNotify)
{
}
NSDictionary * userInfo = [options objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo)
{
}
} 2、- (void)applicationWillResignActive:(UIApplication *)application
说明:当应用程序将要进入非活动状态时执行,在此期间,应用程序不接收消息或事件,比如来电话了。
三、applicationDidBecomeActive
- (void)applicationDidBecomeActive:(UIApplication *)application
说明:当应用程序进入活动状态时执行,这个刚好跟上面那个方法相反。
四、applicationDidEnterBackground
- (void)applicationDidEnterBackground:(UIApplication *)application
说明:当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可。
五、applicationWillEnterForeground
- (void)applicationWillEnterForeground:(UIApplication *)application
说明:当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。
六、applicationWillTerminate
- (void)applicationWillTerminate:(UIApplication *)application
说明:当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。这个需要要设置UIApplicationExitsOnSuspend的键值。一般情况下不会调用。
七、其他监听函数
协议中其他定义的方法的作用:
7.1 applicationDidReceiveMemoryWarning
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
说明:iPhone设备只有有限的内存,如果为应用程序分配了太多内存,操作系统会终止应用程序的运行,在终止前会执行这个方法,通常可以在这里进行内存清理工作防止程序被终止。
7.2 applicationSignificantTimeChange
- (void)applicationSignificantTimeChange:(UIApplication*)application
说明:当系统时间发生改变时执行。
7.3 applicationDidFinishLaunching
- (void)applicationDidFinishLaunching:(UIApplication*)application
说明:当程序载入后执行。
7.4 willChangeStatusBarFrame
- (void)application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame
说明:当StatusBar框将要变化时执行。
7.5 willChangeStatusBarOrientation
- (void)application:(UIApplication*)application willChangeStatusBarOrientation:
(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration
说明:当StatusBar框方向将要变化时执行。
7.6 handleOpenURL
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url
说明:当通过url执行。
7.7 didChangeStatusBarOrientation
- (void)application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
说明:当StatusBar框方向变化完成后执行。
7.8 didChangeSetStatusBarFrame
- (void)application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFrame
说明:当StatusBar框变化完成后执行。