原文链接 http://www.360doc.com/content/15/0918/14/27799428_499912639.shtml

在iOS App中,入口函数并不在根目录下,而是在“Supporting Files”目录的main.m文件的main函数中。这很容易理解,C/C++都是以main为入口。

  1. int main(int argc, char * argv[]) {
  2. @autoreleasepool {
  3. return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  4. }
  5. }

这个函数比较简单,只是调用了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文件,这个关乎着应用程序的生命周期。

  1. #import "AppDelegate.h"
  2. @interface AppDelegate ()
  3. @end
  4. @implementation AppDelegate
  5. // 应用程序第一次启动时执行该函数,如果是手写代码设置应用程序window的rootViewController那么则需要在这里实现。该函数的功能等同于Android中的onCreate函数。
  6. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  7. // Override point for customization after application launch.
  8. return YES;
  9. }
  10. // 应用程序由激活状态切换到未激活状态要执行的函数,例如用户按home键返回主屏幕等。类似于Android中的onPause回调函数
  11. - (void)applicationWillResignActive:(UIApplication *)application {
  12. // 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.
  13. // 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.
  14. }
  15. // 应用程序已进入后台程序时的回调函数,类似于Android中的onStop
  16. - (void)applicationDidEnterBackground:(UIApplication *)application {
  17. // 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.
  18. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  19. }
  20. // 应用程序从未激活状态进入到激活状态要执行的回调函数,过程与WillResignActive相反,等同于Android中的onRestart函数。
  21. - (void)applicationWillEnterForeground:(UIApplication *)application {
  22. // 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.
  23. }
  24. // 应用程序被激活的回调,与didEnterBackground过程想对应。onResume
  25. - (void)applicationDidBecomeActive:(UIApplication *)application {
  26. // 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.
  27. }
  28. // 应用程序即将终止的回调函数
  29. - (void)applicationWillTerminate:(UIApplication *)application {
  30. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  31. }

图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的生命周期【转载】的更多相关文章

  1. Flutter--Flutter中Widget、App的生命周期

    前言 在App的开发过程中,我们通常都需要了解App以及各个页面的生命周期,方便我们在App进入前台时启动一些任务,在进入后台后暂停一些任务.同时,各个页面的生命周期也很重要,每个页面消失时要做一些内 ...

  2. Cordova - 使用Cordova开发iOS应用实战2(生命周期、使用Safari调试)

    Cordova - 使用Cordova开发iOS应用实战2(生命周期.使用Safari调试) 前文我们创建了一个简单的Cordova项目,结构如下: 1,Cordova生命周期事件 (1)device ...

  3. Android App的生命周期是什么

    怎么说呢 看Android一般指的是 Activity的生命周期, 关于app的生命周期, 有明白的大神请告诉我 上面这张图是 网上搜到的一张关于app生命周期的图, 在我看来, 其实就是一个Acti ...

  4. atitit.提升开发效率---使用server控件生命周期 asp.net 11个阶段 java jsf 的6个阶段比較

    atitit.提升开发效率---使用server控件生命周期  asp.net 11个阶段  java jsf 的6个阶段比較 例如以下列举了server控件生命周期所要经历的11个阶段. (1)初始 ...

  5. BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers 远程Event Receivers App级别生命周期

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers  远程Event Receivers App级别生命周期 ...

  6. wp8.1 Study6: App的生命周期管理

    一.概述 应用程序的生命周期详解可以参照Windows8.1开发中msdn文档http://msdn.microsoft.com/library/windows/apps/hh464925.aspx ...

  7. Android开发艺术1之Activity的生命周期

    作为<Android开发艺术探索>这本书的第一篇博客,我就多说几句.本系列博客旨在对书中相关内容进行解读,简化,提供一个入门到提高的流程.不敢说书评,也不能说教程,只希望对有些人有帮助就好 ...

  8. Android开发学习之路--Activity之生命周期

    其实这篇文章应该要在介绍Activity的时候写的,不过那个时候还不怎么熟悉Activity,还是在这里详细介绍下好了.还是参考下官方文档的图吧: 从上面的流程,我们可以看出首先就是打开APP,开始执 ...

  9. python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)

    昨日内容回顾 0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue ...

随机推荐

  1. [NOIP2013] 提高组 洛谷P1979 华容道

    题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...

  2. shell script timer and 無限迴圈

    while : do echo " infinite loop" sleep 2; done

  3. syslog/rsyslog的使用

    syslogd是Linux下的一个记录日志文件服务.从结构来说,可以理解为这个服务下面有一系列的子服务,例如mail.auth.cron.kern等等,这些子服务对外提供日志记录的功能,而当其它的程序 ...

  4. 354. Russian Doll Envelopes

    You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envel ...

  5. 转载——Java与WCF交互(二):WCF客户端调用Java Web Service

    在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttp ...

  6. EasyUI左边树菜单和datagrid分页

    //这个页面是Home.html 1 <!DOCTYPE html> <html> <head> <meta http-equiv="Content ...

  7. Java IO 学习(一)同步/异步/阻塞/非阻塞

    关于IO,同步/异步/阻塞/非阻塞,这几个关键词是经常听到的,譬如: “Java oio是阻塞的,nio是非阻塞的” “NodeJS的IO是异步的” 但是这些东西听多了就容易迷糊,比方说同步是否就是阻 ...

  8. Codeforces 898 A. Rounding

      A. Rounding   time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  9. ORACLE的字符串操作函数

    字符函数——返回字符值 这些函数全都接收的是字符族类型的参数(CHR 除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据库类 ...

  10. Spring Cloud学习总结(非原创)

    文章大纲 一.课程内容总结二.课程学习地址三.学习资料下载四.参考文章 一.课程内容总结   二.课程学习地址 第一天:https://www.jianshu.com/p/a086421f4bfd第二 ...