App程序的本质是在IOS系统与你自定义的代码间架起了一个桥梁,使你的App程序可以调用系统的各种功能,并通过你自定义的代码进行界面的现实,反馈。适当了解些App的基本构成架构,还有比较有意义的。
App程序的Main函数
同C语言类似,IOS app的入口点,也是一个mian函数,它通常定义如下:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
在IOS 的main函数中,完成了以下功能:
1、创建App运行必须的核心对象
2、加载用户定义的storyboard文件来显示用户界面
3、调用用户定义的初始化代码(应该是在application delegate中实现的)
4、启动程序的主循环
其中,2、3项是需要用户自定义的,其余则有系统默认完成。
细看UIApplicationMain的声明如下:
// If nil is specified for principalClassName, the value for NSPrincipalClass from the Info.plist is used. If there is no
// NSPrincipalClass key specified, the UIApplication class is used. The delegate class will be instantiated using init.
UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
可以知道,如果没有特殊定义的话,app的核心类对象类型为UIApplication,application的delegate类型则是AppDelegate类。
IOS App的对象组成
上面说到,在IOS App的main函数中,系统会自动为我们生成一些程序运行必须的核心对象。其中一个很重要的对象是UIApplication,它代表了我们的程序,并肩负起我们程序与系统的交互功能,事件分发循环,以及通知App delegate程序状态转换等职责。
一般的,一个App的对象结构如下图:
由上图可知,IOS App的结构是一个标准的MVC模式,正是因为逻辑与界面的分离,才使得IOS程序能够在不同分辨率的设备上运行。
1、UIApplication对象主要负责事件分发,接收系统及用户事件及通知,同时,将程序状态转换通知给Application Delegate
2、Application Delegate对象则接收来自app的一些通知事件,状态转换事件,同时调用用户自定义的代码执行。在每个App程序中,系统会确保Applciation Delegate的存在及有效性,因此可以将程序初始代码写在这里面。
3、UIWindow对象则可以看做是一个舞台,用户显示的界面即UIView及其子类,均被加载到UIWindow中,界面的切换仅仅是View的切换,一个App中,除非其界面还映射到其他设备的屏幕显示,否则UIWindow是唯一的,且不会更改。
4、View controller 对象。该对象负责管理View。一个View controller对象会管理一个View及一系列该View的子View。当View要显示时,View controller会将其管理的View加载到UIWindow中,进行显示。
5、View objects, control objects, and layer objects。这些对象则是负责在指定的区域内,对界面进行显示,同时对于事件进行响应。layer objects则类似于一个内容集合容器,通过layer object可以实现动画及更生动的界面显示。
The Main run loop
IOS app的主循环函数负责处理所有的用户相关事件。在程序加载之初,UIApplication对象会启动main loop,同时利用main loop进行事件处理及界面更新。
main函数运行在程序的主线程上。
程序处理事件的流程如下图所示:
事件的处理流程还是比较清晰的。首先用户触发事件,系统会通过UIKit设置的端口,将该事件分配到对应的App的事件队列中。事件队列的事件会依次进入程序的主循环中,并有UIApplication对象第一个接收,UIApplication对象会对事件进行进一步的分发。
例如,一个触摸事件,会被UIApplication对象分发到UIWindow对象中,再有UIWindow对象进一步分发到激发该事件的View对象中。即事件在App中是层层分发的,直到能够处理该事件的对象为止。而处于首位的,则是UIApplication对象。
对于事件的分发,这里有涉及到两个概念:responder objects及responder chain。摘录如下:
Some events, such as touch and remote control events, are handled by your app’s responder objects. Responder objects are everywhere in your app. (The UIApplication
object, your view objects, and your view controller objects are all examples of responder objects.) Most events target a specific responder object but can be passed to other responder objects (via the responder chain) if needed to handle an event. For example, a view that does not handle an event can pass the event to its superview or to a view controller.
IOS App程序的状态切换
IOS程序按照运行状态可以分为五个状态,如下表所示:
它的转换示意图如下
其中需要注意的时Suspended状态,这个状态实际上就是一种僵尸状态,处于这种状态的App不会执行任何代码,而且当系统内存不足时,系统可能会将处于这种状态的App移除内存,而这时候是没有任何通知的!(在App由Background进入Suspended时,也是没有任何通知的)
只有当App处于Background状态是,这时候系统退出App是,用户才可以得到 applicationWillTerminate:通知。
另外,当手机用户通过进程管理器关闭处于Background状态的程序时,程序也不会得到任何通州。
Application delegate对应的程序状态方法
每当程序状态切换时,UIApplication 对象会通知Application delegate对象,同时,delegate会调用响应的方法让我们做出响应。其状态对应方法如下:
-
application:willFinishLaunchingWithOptions:
—This method is your app’s first chance to execute code at launch time. -
application:didFinishLaunchingWithOptions:
—This method allows you to perform any final initialization before your app is displayed to the user. -
applicationDidBecomeActive:
—Lets your app know that it is about to become the foreground app. Use this method for any last minute preparation. -
applicationWillResignActive:
—Lets you know that your app is transitioning away from being the foreground app. Use this method to put your app into a quiescent state. -
applicationDidEnterBackground:
—Lets you know that your app is now running in the background and may be suspended at any time. -
applicationWillEnterForeground:
—Lets you know that your app is moving out of the background and back into the foreground, but that it is not yet active. -
applicationWillTerminate:
—Lets you know that your app is being terminated. This method is not called if your app is suspended.
参考资料