OS开发之旅之App的生命周期【转载】
原文链接 http://www.360doc.com/content/15/0918/14/27799428_499912639.shtml
在iOS App中,入口函数并不在根目录下,而是在“Supporting Files”目录的main.m文件的main函数中。这很容易理解,C/C++都是以main为入口。
- int main(int argc, char * argv[]) {
- @autoreleasepool {
- return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
- }
- }
这个函数比较简单,只是调用了UIApplicationMain方法来启动整个应用程序,前两个参数就是普通C/C++的命令行参数,这里我们可以忽略。主要看后面两个参数。后两个参数分别表示程序的主要类(principal class)和app代理类(delegate class)。如果主要类(principal class)为nil,将从Info.plist中获取,如果Info.plist中不存在对应的key,则默认为UIApplication;App代理类(delegate class)将在新建工程时创建,即AppDelegate,应用程序的整个生命周期都由它来代理。
APP生命周期
根据UIApplicationMain函数,程序将进入AppDelegate.m,这个文件是xcode新建工程时自动生成的。下面看一下AppDelegate.m文件,这个关乎着应用程序的生命周期。
- #import "AppDelegate.h"
- @interface AppDelegate ()
- @end
- @implementation AppDelegate
- // 应用程序第一次启动时执行该函数,如果是手写代码设置应用程序window的rootViewController那么则需要在这里实现。该函数的功能等同于Android中的onCreate函数。
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- // Override point for customization after application launch.
- return YES;
- }
- // 应用程序由激活状态切换到未激活状态要执行的函数,例如用户按home键返回主屏幕等。类似于Android中的onPause回调函数
- - (void)applicationWillResignActive:(UIApplication *)application {
- // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
- // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
- }
- // 应用程序已进入后台程序时的回调函数,类似于Android中的onStop
- - (void)applicationDidEnterBackground:(UIApplication *)application {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
- }
- // 应用程序从未激活状态进入到激活状态要执行的回调函数,过程与WillResignActive相反,等同于Android中的onRestart函数。
- - (void)applicationWillEnterForeground:(UIApplication *)application {
- // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
- }
- // 应用程序被激活的回调,与didEnterBackground过程想对应。onResume
- - (void)applicationDidBecomeActive:(UIApplication *)application {
- // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
- }
- // 应用程序即将终止的回调函数
- - (void)applicationWillTerminate:(UIApplication *)application {
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
- }
application:willFinishLaunchingWithOptions:
—这方法在应用第一次启动时执行,即只执行一次。类似于Android中的onCreate函数。application:didFinishLaunchingWithOptions:
—这个函数允许你在应用显示在用户面前之前进行最后的初始化工作。applicationDidBecomeActive:
—在应用程序成为前台程序时要执行的回调函数,类似于Android中的onResume函数。applicationWillResignActive:
—在应用程序从前台转换到后台程序时会调用的函数,类似于Android中的onStop函数。applicationDidEnterBackground:
—应用程序进入到后台状态的回调函数,此时的应用程序可能在任何时刻被挂起。applicationWillEnterForeground:
—应用程序从后台进入到前台的回调函数,但此时应用程序还不是激活状态,类似于Android中的onRestart函数。applicationWillTerminate:
—应用程序将要被终止时的回调函数,如果你的程序只是被挂起,那么不会回调该函数,类似于Android中的onDestory函数。
图1 图2
如上图1所示,应用程序启动UIApplication,此时主线程( UI线程 )的事件循环就会开启。并且会将App的生命周期代理给AppDelegate,首先会调用
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions ,我们又会在该函数中设置AppDelegate中window的rootViewController为我们的第一个页面(更多的情况是系统自动加载应用程序的默认的storyboard界面),我们会在自己的ViewController中设计UI,因此应用程序window中就加载了我们的UI,此时应用程序就从最初的not running状态到了Active状态。
UI的线程安全
在上文中我们提到了应用程序启动时会启动一个消息循环,并且这个消息循环是在主线程中的。开发过Android应用程序的同学都知道,更新UI必须在主线程中,这是因为UI控件并不是线程安全的,在Android中UI控件都是ThreadLocal的,这个ThreadLocal就是就是主线程的ThreadLocal,可以简单的理解为UI控件的操作只能在主线程中执行才是安全的,如果在其他线程中操作就会抛出异常,这就是UI控件的非线程安全性。
iOS中的UI控件也不是线程安全的。因为App中UI更新频率时是很高的,如果UI是线程安全的,也就是UI控件在子线程中可以修改、更新等,那么系统必须要对各种UI操作进行锁操作,加锁、解锁、系统调度等会消耗大量的CPU资源,这样就会导致效率底下,而且容易导致死锁问题。因此,UI操作只能在主线程中。官方解释如下 :
Threading ConsiderationsManipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.
UIWindow与UIView
UIWindow就是应用程序窗口,简单理解就是整个手机屏幕。UIWindow的主要功能就是提供一个区域来显示UI视图和将事件分发给视图。在应用加载时,我们会设置或者由系统从plist文件中加载UIWindow的rootViewController,在UIViewController中又包含了各种UI控件,当应用启动时,启动了消息循环,回调App的生命周期函数,将UI控件绘制到UIWindow中,然后又通过UIWindow将用户的各种操作通过事件的形式分发给UI控件,至此整个App就运转起来了。
OS开发之旅之App的生命周期【转载】的更多相关文章
- Flutter--Flutter中Widget、App的生命周期
前言 在App的开发过程中,我们通常都需要了解App以及各个页面的生命周期,方便我们在App进入前台时启动一些任务,在进入后台后暂停一些任务.同时,各个页面的生命周期也很重要,每个页面消失时要做一些内 ...
- Cordova - 使用Cordova开发iOS应用实战2(生命周期、使用Safari调试)
Cordova - 使用Cordova开发iOS应用实战2(生命周期.使用Safari调试) 前文我们创建了一个简单的Cordova项目,结构如下: 1,Cordova生命周期事件 (1)device ...
- Android App的生命周期是什么
怎么说呢 看Android一般指的是 Activity的生命周期, 关于app的生命周期, 有明白的大神请告诉我 上面这张图是 网上搜到的一张关于app生命周期的图, 在我看来, 其实就是一个Acti ...
- atitit.提升开发效率---使用server控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比較
atitit.提升开发效率---使用server控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比較 例如以下列举了server控件生命周期所要经历的11个阶段. (1)初始 ...
- BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers 远程Event Receivers App级别生命周期
BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers 远程Event Receivers App级别生命周期 ...
- wp8.1 Study6: App的生命周期管理
一.概述 应用程序的生命周期详解可以参照Windows8.1开发中msdn文档http://msdn.microsoft.com/library/windows/apps/hh464925.aspx ...
- Android开发艺术1之Activity的生命周期
作为<Android开发艺术探索>这本书的第一篇博客,我就多说几句.本系列博客旨在对书中相关内容进行解读,简化,提供一个入门到提高的流程.不敢说书评,也不能说教程,只希望对有些人有帮助就好 ...
- Android开发学习之路--Activity之生命周期
其实这篇文章应该要在介绍Activity的时候写的,不过那个时候还不怎么熟悉Activity,还是在这里详细介绍下好了.还是参考下官方文档的图吧: 从上面的流程,我们可以看出首先就是打开APP,开始执 ...
- python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)
昨日内容回顾 0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue ...
随机推荐
- 水晶报表 IE设置
水晶报表:Crystal Reports(水晶报表)是一款商务智能(BI)软件,主要用于设计及产生报表.水晶报表是业内最专业.功能最强的报表系统,它除了强大的报表功能外,最大的优势是实现了与绝大多数流 ...
- Atcoder CODE FESTIVAL 2017 qual C C - Inserting 'x' 回文串
题目链接 题意 给定字符串\(s\),可以在其中任意位置插入字符\(x\). 问能否得到一个回文串,若能,需插入多少个\(x\). 思路 首先统计出现次数为奇数的字符\(cnt\). \(cnt\ge ...
- duilib入门简明教程 -- 完整的自绘标题栏(8) (转)
原文转自:http://www.cnblogs.com/Alberl/p/3343763.html 看了前面那么多教程,相信对duilib已有基本映像了,我们就快马加鞭,做出一个完整的自绘标题 ...
- php通过$_SERVER['HTTP_USER_AGENT']获取浏览器相关参数
最近不忙,同事在忙一个app项目.当听到领导安排让他做一个判断苹果还是安卓手机,如果是安卓手机下载安卓app.如果是苹果手机下载苹果app;然后我就上网搜了一下学习学习: php通过$_SERVER[ ...
- java获取整数的各位数值
第一种是取模运算 int qian =input/1000; //千位除以1000 int bai = input/100%10;//百位除以100%10 int shi = input%100/10 ...
- ZSTU 4248 KI的目标(dfs)
KI的目标 Time Limit: 2 Sec Memory Limit: 128 MB ...
- 记一次kubernetes集群异常: kubelet连接apiserver超时
Background kubernetes是master-slave结构,master node是集群的大脑, 当master node发生故障时整个集群都"out of control&q ...
- Unique Binary Search Tree - Leetcode
Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...
- 非常有用的开发工具之Android Studio插件
我们都知道Eclipse开发Android将在今年年底google不再继续提供相应的开发支持,转而开始强烈发展Android Studio,现在我就分享几款能帮助团队提升工作效率的几个Android ...
- 【mybatis】从一个错误,看mybatis中的#和$的区别
事情的发展是这样的: 因为一个需求,需要在java中拼接出一个完整的sql语句,然后将整条sql语句传递给mybatis执行. mapper.java是这样的: int insertMaster(Wo ...