一:
main函数入口:
主要完成三个功能:
1,从可用Storyboard文件加载用户界面
2,调用AppDelegate自定义代码来做一些初始化设置
3,将app放入Main Run Loop环境中来响应和处理与用户交互产生的事件
UIApplication对象
用户与iOS设备交互时产生的事件(Multitouch Events,Motion Event,Remote Control Event)交由UIApplication对象来分发给control objects(UIControl)对应的target objects来处理并且管理整个事件循环,而一些关于app运行时重要事件委托给app delegate来处理。
App delegate对象
App delegate对象遵循UIApplicationDelegate协议,响应app运行时重要事件(app启动、app内存不足、app终止、切换到另一个app、切回app),主要用于app在启动时初始化一些重要数据结构;例如,初始化UIWindow,设置一些属性,为window添加rootViewController。
View controller对象
View Controller有一个view属性是view层次结构中的根view,你可以添加子view来构建复杂的view;controller有一些viewDidLoad、viewWillAppear等方法来管理view的生命周期;由于它继承UIResponder,所有还会响应和处理用户事件。
Documents和data model对象
data model对象主要用来存储数据。例如,饿了么app在搜索切换地址后,有历史记录搜索地址历史,当app下次启动时,读取和显示搜索地址历史。
document对象(继承UIDocument)用来管理一些或所有的data model对象。document对象并不是必须的,但提供一种方便的方式来分组属于单个文件或多个文件的数据。
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外观和构建复杂的动画。
大Boss:
Main Run Loop
Main Run Loop
主要作用是处理所有与用户相关的事件。UIApplication
对象在启动时就设置main run loop和使用它来处理事件和更新基于view的界面。正如它名字所示,main run loop是运行在应用程序的主线程。这样就确保与接收到用户相关的事件被
有序地处理
应用程序把事件放入队列,然后逐个分发到main run loop来执行。UIApplication
对象是第一个对象接收到事件,然后决定怎样处理它。一个touch event通常都被分发到main window对象,然后依次分发到发生触碰的view。其他event的接收事件对象路径可能有点不同。
程序运行时的几种状态:
- Not running:app还没运行
- Inactive:app运行在foreground但没有接收事件
- Active:app运行在foreground和正在接收事件
- Background:运行在background和正在执行代码
- Suspended:运行在background但没有执行代码
应用进入运行时会进入APPdelegate里面执行代理方法:application:willFinishLaunchingWithOptions:
- 这个方法是你在启动时的第一次机会来执行代码application:didFinishLaunchingWithOptions:
- 这个方法允许你在显示app给用户之前执行最后的初始化操作applicationDidBecomeActive:
- app已经切换到active状态后需要执行的操作applicationWillResignActive:
- app将要从前台切换到后台时需要执行的操作applicationDidEnterBackground:
- app已经进入后台后需要执行的操作applicationWillEnterForeground:
- app将要从后台切换到前台需要执行的操作,但app还不是active状态applicationWillTerminate:
- app将要结束时需要执行的操作1,当app启动时,首先由
not running
状态切换到inactive
状态,此时调用application:didFinishLaunchingWithOptions:
方法;然后由inactive
状态切换到active
状态,此时调用applicationDidBecomeActive:
方法
2,当app发生中断时,由active
状态切换到inactive
状态,此时调用applicationWillResignActive:
方法。3,当切换到另一个app时,由状态
active
切换到inactive
,此时调用applicationWillResignActive:
方法;然后从inactive
状态切换到running
状态,此时调用applicationDidEnterBackground:
方法4,而当切换回本来的app时,由
running
状态切换到inactive
状态,此时调用applicationWillEnterForeground:
方法,然后由inactive
状态切换到active
状态,调用applicationDidBecomeActive:
方法。
5,锁屏时,由状态active
切换到inactive
,此时调用applicationWillResignActive:
;然后再由inactive
状态切换到running
状态,此时调用applicationDidEnterBackground:
方法
应用程序的终止
系统常常是为其他app启动时由于内存不足而回收内存最后需要终止应用程序,但有时也会是由于app很长时间才响应而终止。如果app当时运行在后台并且没有暂停,系统会在应用程序终止之前调用
applicationWillTerminate:
来保存用户的一些重要数据以便下次启动时恢复到app原来的状态。
总结:应用程序从启动到结束过程中有哪些关键对象在参与,以及当用户与系统交互时产生事件时,系统利用main run loop来管理事件循环,决定将事件交给系统哪些对象处理和如何处理。而当app启动、来回切换app和锁屏时,app的状态如何切换和调用对应的哪些
app delegate
对象来处理