Main函数入口
所有基于C编写的app的入口都是main函数,iOS中Xcode自动生成,如下。
#import <UIKit/UIKit.h>
#import "YYAppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([YYAppDelegate class]));
}
}
- main
main函数有两个参数,argc是命令行总的参数个数,argv[]是argc个参数,其中第0个参数是程序的全名,剩下的参数命令行后面跟的用户输入的参数 - UIApplicationMain
UIApplicationMain主要是创建app的几个核心对象
- File’s Owner 对象,实际上就是 UIApplication 的实例。
- First Responder 对象。每个程序都会有一个第一响应者,比如鼠标事件,键盘事件等,它就是对应的那个对象。比如多文档程序中,menu的响应事件一般都是连接到FirstResponder中去的,因为主界面一般都在别的nib里面,此时的FirstResponder就是你的那个主nib的FileOwner。
- Delegate 对象。
- Window。应用程序启动的时候所显示的窗口。
来处理以下过程:
- 从可用Storyboard文件中加载用户界面,
- 调用AppDelegate自定义代码来做一些初始化设置
- 将app放在主线程中,main run loop环境中来响应和处理与用户交互产生的事件。
int UIApplicationMain (
int argc,
char *argv[],
NSString *principalClassName,
NSString *delegateClassName
);
注释:
第四个参数是应用程序类的代理类,其值如果是nil,那么在nib/xib(在info.plist文件中指定,key是NSMainNibFile,使用Storyboards后则key为MainStoryboard)文件中你就必须提供一个delegate对象给这个参数.
通过上面的语句,创建UIApplication实例。同时,查看应用程序的 Info.plist 文件(该文件记录了一些应用程序的基础信息,比如程序名称,版本,图标等)。该文件还包含应用程序资源文件的名称(nib文件,名称用NSMainNibFile键指定)。如下所示:
此函数会根据principalClassName创建UIApplication对象,然后根据delegateClassName创建一个delegate对象,并将UIApplication对象中的delegate属性设置为delegate对象。接着会建立事件响应环.
虽然返回类型定义的是int,但此函数永远不会return,当用户点击home键后,程序便进入后台了。
事件(Multitouch Events,Motion Event,Remote Control Event)交由UIApplication对象来分发给control objects(UIControl)对应的target objects来处理并且管理整个事件循环,而一些关于app运行时重要事件委托给app delegate来处理。
举个简单的例子,其实ios的消息循环 就如我们的邮政系统,UIAppliationMain函数了就是建立这个邮政系统的机构 ,也就相当于我们的政府,UIApplication就是邮局,用户对手机的各种输入,就相当于人们寄送了一些信件,邮局就会根据地址把信送到收件人手里,而UIApplicationDelegate就是其中的一部分收件人。而收件人收到信后会做何种处理呢?收件人一看是寄给自己的,可能就打开看了,可能看了信后做了某些事情,就相当于程序里某个对象接到消息后做了某些处理;还有可能就是收件人收到信后一看,不是给自己的,是转给某人A的,这时候收件人就把信件交给了A,然后A看完信后做了后做了某些事情。这就是我们所说的事件响应链(responder类及其子类相关),这里不多说,以后会有介绍。还有种情况,就是人物A收到信后,一看是C寄来的,这封信有可能是寄给A的,也有可能是要求A转给B的,但是A非常讨厌C,就把信扔到一边不再理会,这就造成了事件响应链的断裂。
其他对象:
App delegate对象 :遵循UIApplicationDelegate协议,响应app运行时重要事件(app启动、app内存不足、app终止、切换到另一个app、切回app),主要用于app在启动时初始化一些重要数据结构;例如,初始化UIWindow,设置一些属性,为window添加rootViewController。
View Controller对象
viewController有一个view属性是view层次结构中的根view,你可以添加子view来构建复杂的view;controller有一些viewDidLoad、viewWillAppear等方法来管理view的生命周期;由于它继承UIResponder,所有还会响应和处理用户事件。UIWindow对象
UIWindow对象位于view层次结构中的最顶层,它充当一个基本容器而不显示内容,如果想显示内容,添加一个content view到window。它也是继承UIResponder,所以它也是会响应和处理用户事件。View、control、layer对象
View对象可以通过addSubview和removeFromSuperview 等方法管理view的层次结构,使用layoutIfNeeded和setNeedsLayout等方法布局view的层次结构,当你发现系统提供view已经满足不了你想要的外观需求时,可以重写drawRect方法或通过layer属性来构造复杂的图形外观和动画。还有一点,UIView也是继承UIResponder,所以也能够处理用户事件。Control对象通常就是处理特定类型用户交互的View,常用的有button、switch、text field等。除了使用View和Control来构建view层次结构来影响app外观之外,还可以使用Core Animation框架的Layer对象来渲染view外观和构建复杂的动画。
程序状态与切换
- Not running:app还没运行
- Inactive:app运行在foreground但没有接收事件
- Active:app运行在foreground和正在接收事件
- Background:运行在background和正在执行代码
- Suspended:运行在background但没有执行代码
而状态转换时都会掉用delegate对象对应的方法来响应状态变化。
- application:willFinishLaunchingWithOptions: - 这个方法是你在启动时的第一次机会来执行代码
application:didFinishLaunchingWithOptions: - 这个方法允许你 在显示app给用户之前执行最后的初始化操作 - applicationDidBecomeActive: - app已经切换到active状态后需要执行的操作
- applicationWillResignActive: - app将要从前台切换到后台时需要执行的操作
- applicationDidEnterBackground: - app已经进入后台后需要执行的操作
- applicationWillEnterForeground: - app将要从后台切换到前台需要执行的操作,但app还不是active状态
- applicationWillTerminate: - app将要结束时需要执行的操作