iOS应用程序的生命周期
iOS应用程序一般都是由自己编写的代码和系统框架(system frameworks)组成,系统框架提供一些基本infrastructure给所有app来运行,而你提供自己编写的代码来定制app的外观和行为。因此,了解iOS infrastructure和它们如何工作对编写app是很有帮助的。
Main函数入口
所有基于C编写的app的入口都是main
函数,但iOS应用程序有点不同。不同就是你不需要为iOS应用程序而自己编写main
函数,当你使用Xcode创建工程的时候就已经提供了。除非一些特殊情况,否则你不应该修改Xcode提供的main
函数实现。示例代码如下:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
上面实例代码中有一个很重要的函数UIApplicationMain,它主要是创建app的几个核心对象来处理以下过程:
- 从可用
Storyboard
文件加载用户界面 - 调用
AppDelegate
自定义代码来做一些初始化设置 - 将app放入
Main Run Loop
环境中来响应和处理与用户交互产生的事件
应用程序的架构
iOS应用程序都遵循Model-View-Controller
的架构,Model
负责存储数据和处理业务逻辑,View
负责显示数据和与用户交互,Controller
是两者的中介,协调Model
和View
相互协作。它们的通讯规则如下:
Controller
能够访问Model
和View
,Model
和View
不能互相访问MVC Communication - Reference from Stanford University.png当
View
与用户交互产生事件时,使用target-action
方式来处理MVC Communication - Reference from Stanford University.png当
View
需要处理一些特殊UI逻辑或获取数据源时,通过delegate
或data source
方式交给Controller
来处理MVC Communication - Reference from Stanford University.pngModel
不能直接与Controller
通信,当Model
有数据更新时,可以通过Notification
或KVO (Key Value Observing)
来通知Controller
更新View
MVC Communication - Reference from Stanford University.png
了解iOS的MVC设计模式之后,我们从下图来了解在MVC模式下iOS应用程序有哪些关键对象以及它们职责主要是什么?
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外观和构建复杂的动画。
Main Run Loop
一个iOS应用程序的main run loop主要作用是处理所有与用户相关的事件。UIApplication
对象在启动时就设置main run loop和使用它来处理事件和更新基于view的界面。正如它名字所示,main run loop是运行在应用程序的主线程。这样就确保与接收到用户相关的事件被有序地处理。
下图显示main run loop的架构和用户事件最终是怎样被应用程序处理。当用户与设备交互时,系统就会生成与交互关联的事件,然后被应用程序的UIKit通过一个特殊的端口来分发。应用程序把事件放入队列,然后逐个分发到main run loop来执行。UIApplication
对象是第一个对象接收到事件,然后决定怎样处理它。一个touch event通常都被分发到main window对象,然后依次分发到发生触碰的view。其他event的接收事件对象路径可能有点不同。
大多数的事件通过使用main run loop来分发,但有些不是。有些事件被发送到一个delegate对象或传递到你提供的block中。想了解更多如何处理大多数类型的事件,其中包括touch、remote control、motion、accelerometer和gyroscopic等事件,请查阅Event Handle Guide for iOS。
应用程序的状态和多任务
有时系统会从app一种状态切换另一种状态来响应系统发生的事件。例如,当用户按下home键、电话打入、或其他中断发生时,当前运行的应用程序会切换状态来响应。应用程序的状态有以下几种:
- Not running:app还没运行
- Inactive:app运行在foreground但没有接收事件
- Active:app运行在foreground和正在接收事件
- Background:运行在background和正在执行代码
- Suspended:运行在background但没有执行代码
大多数发生状态转换时都会调用delegate
对象对应的方法来响应app的状态改变。下面汇总了delegate
对象的所有方法,当app状态发生转换时,你可能会使用到它们。
application:willFinishLaunchingWithOptions:
- 这个方法是你在启动时的第一次机会来执行代码application:didFinishLaunchingWithOptions:
- 这个方法允许你在显示app给用户之前执行最后的初始化操作applicationDidBecomeActive:
- app已经切换到active状态后需要执行的操作applicationWillResignActive:
- app将要从前台切换到后台时需要执行的操作applicationDidEnterBackground:
- app已经进入后台后需要执行的操作applicationWillEnterForeground:
- app将要从后台切换到前台需要执行的操作,但app还不是active状态applicationWillTerminate:
- app将要结束时需要执行的操作
现在讲下app启动、来回切换app和锁屏时状态的切换和调用对应哪些delegate对象的方法:
app启动和active/inactive
Launch and active/inactive from Apple WWDC 2011 Session如图所示,当app启动时,首先由
not running
状态切换到inactive
状态,此时调用application:didFinishLaunchingWithOptions:
方法;然后由inactive
状态切换到active
状态,此时调用applicationDidBecomeActive:
方法。Launch and active/inactive 2 from Apple WWDC 2011 Session当app发生中断时,由
active
状态切换到inactive
状态,此时调用applicationWillResignActive:
方法。来回切换app
Switch from an app from Apple WWDC 2011 Session如图所示,当切换到另一个app时,由状态
active
切换到inactive
,此时调用applicationWillResignActive:
方法;然后从inactive
状态切换到running
状态,此时调用applicationDidEnterBackground:
方法。Switch to an app from Apple WWDC 2011 Session而当切换回本来的app时,由
running
状态切换到inactive
状态,此时调用applicationWillEnterForeground:
方法,然后由inactive
状态切换到active
状态,调用applicationDidBecomeActive:
方法。锁屏
Device lock from Apple WWDC 2011 Session如何所示,当手机锁屏时,由状态
active
切换到inactive
,此时调用applicationWillResignActive:
;然后再由inactive
状态切换到running
状态,此时调用applicationDidEnterBackground:
方法。更多关于app状态切换以及调用
app delegate
哪些方法,请观看WWDC 2011 Session的session_320__adopting_multitasking_in_your_app视频。
应用程序的终止
系统常常是为其他app启动时由于内存不足而回收内存最后需要终止应用程序,但有时也会是由于app很长时间才响应而终止。如果app当时运行在后台并且没有暂停,系统会在应用程序终止之前调用applicationWillTerminate:
来保存用户的一些重要数据以便下次启动时恢复到app原来的状态。
总结
本文总结了iOS应用程序从启动到结束过程中有哪些关键对象在参与,以及当用户与系统交互时产生事件时,系统利用main run loop来管理事件循环,决定将事件交给系统哪些对象处理和如何处理。而当app启动、来回切换app和锁屏时,app的状态如何切换和调用对应的哪些app delegate
对象来处理。
原文链接:http://www.jianshu.com/p/aa50e5350852
著作权归作者所有,转载请联系作者获得授权。
iOS应用程序的生命周期的更多相关文章
- iOS 应用程序的生命周期
iOS 应用程序的生命周期(网络资源总结) http://blog.csdn.net/totogo2010/article/details/8048652 http://www.cocoachina. ...
- [转载] iOS应用程序的生命周期
iOS应用程序的生命周期 2015-06-23 iOS大全 (点击上方蓝字,快速关注我们) iOS应用程序一般都是由自己编写的代码和系统框架(system frameworks)组成,系统框架提供一些 ...
- [ios基础]IOS应用程序的生命周期问题
—程序的生命周期 a.程序的生命周期是指应用程序启动到应用程序结束整个阶段的全过程 b.每一个IOS应用程序都包含一个UIApplication对象,IOS系统通过该U ...
- 浅析 - iOS应用程序的生命周期
1.应用程序的状态 状态如下: Not running 未运行 程序没启动 Inactive 未激活 程序在前台运行,不过没有接收到事件.在没有事件处理情况下程序通 ...
- [转]iOS 应用程序的生命周期
OS的应用程序的生命周期,还有程序是运行在前台还是后台,应用程序各个状态的变换,这些对于开发者来说都是很重要的. iOS系统的资源是有限的,应用程序在前台和在后台的状态是不一样的.在后台时,程序会受到 ...
- iOS开发-程序的生命周期
为了更好的管理程序,了解程序的生命周期是很有必要的. 运行结果: 1.首次启动: 2015-05-26 17:33:28.362 Live[4858:214241] 程序开始 2015-05-26 1 ...
- IOS学习1——IOS应用程序的生命周期及基本架构
一.应用程序的状态和多任务 有时系统会从app一种状态切换另一种状态来响应系统发生的事件.例如,当用户按下home键.电话打入.或其他中断发生时,当前运行的应用程序会切换状态来响应.应用程序的状态有以 ...
- iOS 应用程序的生命周期(转CocoaChina)
对于iOS应用程序,关键是要知道你的应用程序是否正在前台或后台运行.由于系统资源在iOS设备上较为有限,一个应用程序必须在后台与前台有不同的行为.操作系统也会限制你的应用程序在后台的运行,以提高电池寿 ...
- 墓碑机制与 iOS 应用程序的生命周期
① 应用程序的状态 iOS 应用程序一共有 5 种状态: Not running:应用未运行 Inactive:应用运行在 foreground 但没有接收事件 Active:应用运行在 foregr ...
随机推荐
- mysql状态取反(0变1,1变0)
如果要改变status状态 update table_name status=ABS(status-1); //取绝对值 则0-->1 1-->0
- .NET LINQ查询语法与方法语法
LINQ 查询语法与方法语法 通过使用 C# 3.0 中引入的声明性查询语法,介绍性 LINQ 文档中的多数查询都被编写为查询表达式. 但是,.NET 公共语言运行时 (CLR) 本身并不具 ...
- Odoo9是如何计算预定交付日期的
计算预定日期目的是按计划交付.接收等.根据不同公司习惯,Odoo会通过调度器自动生成预定日期,Odoo调度器计算每一行的每件事情,无论是生产订单.交货单.销售订单等,依据Odoo中配置的不同交付时间( ...
- vim for windows 简介
普通人的编辑利器--VIM (for windows) 本文转载自 FROM Vincent_czz2005年5月,我开始用VIM.此后渐入佳境,原来因版权自律而放弃盗版UltraEdit的遗憾一扫而 ...
- Android笔记:异步消息处理
1. Message Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据.上一小节中我们使用到了Message 的what 字段,除此之外还可以使用arg1 ...
- C#回顾 - 7.如何使用反射实现工厂模式?
工厂模式是一种比较常用的设计模式,其基本思想在于使用不同的工厂类型来打造不同产品的部件.例如,我们在打造一间屋子时,可能需要窗户.屋顶.门.房梁.柱子等零部件.有的屋子需要很多根柱子,而有的屋子又不需 ...
- PS 使用的常用命令
本文记载一些简单的PS使用的命令 1. photoshop 画完矩形调整大小方法: a.画完矩形. b.按下Ctrl+T. c.拖边线上的小正方形就是了. 2. 画圆或者矩形时,按住shift 可以变 ...
- CocoaPods安装和使用
CocoaPods是iOS最常用的第三方类库管理工具,绝大部分有名的开源类库都支持CocoaPods. CocoaPods是用Ruby实现的,要想使用它首先需要有Ruby的环境.幸运的是OS X系统默 ...
- [数据库]cakephp操作ENUM、tinyint等类型的一点说明
之前无法正常更新ENUM类型的数据,感觉是框架函数实现的bug. 问题很诡异,因为INIT的时候是可以成功写入的,没理由UPDATE的时候不成功. 前后琢磨了一下午,发现了一点蛛丝马迹才终于想通.问题 ...
- React native 的弹出层(输入)效果
/*弹出层测试*/ import React,{Component} from 'react'; import { StyleSheet, View, Image, Text, TouchableOp ...