最近看视频了解了一下应用程序的启动原理,这里就做一个博客和大家分享一下,相互讨论,如果有什么补充或不同的意见可以提出来!

1、程序入口

 众所周知,一个应用程序的入口一般是一个 main 函数,iOS也不例外,在工程的 Supporting Files 文件夹中你可以找到main.m,他就是程序的入口。

  代码:

int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil,NSStringFromClass([AppDelegate class]));
}
}

2、UIApplicationMain函数参数解析

 UIApplicationMain 函数的声明:

// If nil is specified for principalClassName, the value for NSPrincipalClass from the Info.plist is used. If there is no
// NSPrincipalClass key specified, the UIApplication class is used. The delegate class will be instantiated using init.
int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
  • 第一个参数 argc 和 第二个参数 argv 为C语言的值,在这里可以不做考虑。

  • 第三个参数 principalClassName:主程序类名,由英文注释可知,当值为 nil 时,默认使用的就是 UIApplication

  • 第四个参数:delegateClassName:代理类名,在 iOS 中默认就是随工程一起创建出来的AppDelegate。

  第四个参数的类型是一个字符串,但是在主函数却是 NSStringFromClass([AppDelegate class]) 。NSStringFromClass() 函数是将一个类名转为字符串的一种特殊转换函数,[AppDelegate class] 则是反射得到AppDelegate 对象的类名。

  和 NSStringFromClass() 函数类似的一系列函数声明:

FOUNDATION_EXPORTNSString *NSStringFromSelector(SEL aSelector); // 函数名转字符串
FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName); // 字符串转函数名 FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass); // 类名转字符串
FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString *aClassName); // 字符串转类名 FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) NS_AVAILABLE(10_5, 2_0); // 协议名转字符串
FOUNDATION_EXPORT Protocol * __nullable NSProtocolFromString(NSString *namestr) NS_AVAILABLE(10_5, 2_0); // 字符串转协议名

3、UIApplicationMain底层实现

(1)根据 principalClassName 提供类名创建 UIApplication 对象

(2)创建 UIApplicationDelegate 对象,并且成为 UIApplication 对象代理,app.delete = delegate

(3)开启一个主运行循环,处理事件,可以保持程序一直运行。

(4)加载 info.plist,并且判断 Main Interface 有木有指定 main.storyboard,如果指定,就会去加载

(5)如果有指定,加载 main.stroyboard 做的事情

  创建窗口,也就会说执行 AppDelegate 中的代理方法

  加载 main.storyboard, 并且加载 main.storyboard 指定的控制器

  把新创建的控制器作为窗口的跟控制器,让窗口显示出来

(6)如果没有指定,就在 AppDelegate 的代理方法 - (BOOL)application: didFinishLaunchingWithOptions:中创建一个UIWindow 对象作为主窗口

  代码:

// 程序启动完成的时候
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch. // 1.创建窗口,注意窗口必须要有尺寸,尺寸跟屏幕一样大的尺寸,窗口不要被释放
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor redColor]; // 2.创建窗口的根控制器
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor yellowColor]; [vc.view addSubview:[UIButton buttonWithType:UIButtonTypeContactAdd]]; // 如果设置窗口的跟控制器,默认就会把控制器的view添加到窗口上
// 设置窗口的跟控制器,默认就有旋转功能
self.window.rootViewController = vc; // 3.显示窗口
[self.window makeKeyAndVisible]; return YES;
}

 图解:

  官方帮助文档图解:

【原】iOS学习之应用程序的启动原理的更多相关文章

  1. iOS常见文件及程序的启动原理

    一. iOS中常见文件 (一). Xcode6之前 创建项目,默认可以看见一个存放框架的文件夹 info文件以工程文件名开头,如:第一个项目-Info.plist 项目中默认有一个PCH文件 (二). ...

  2. iOS的常见文件及程序的启动原理

    一. iOS中常见文件 (一). Xcode6之前 创建项目,默认可以看见一个存放框架的文件夹 info文件以工程文件名开头,如:第一个项目-Info.plist 项目中默认有一个PCH文件 (二). ...

  3. iOS程序的启动原理

    一.在一些老的项目中,有很多不是通过代码添加窗口和跟控制器.是通过设置MainInterface(设置最主要的xib),在xib中通过图形化的操作设置应用程序的代理->设置窗口->设置根控 ...

  4. 【转载】Spring boot学习记录(三)-启动原理解析

    前言:本系列文章非本人原创,转自:http://tengj.top/2017/04/24/springboot0/ 正文 我们开发任何一个Spring Boot项目,都会用到如下的启动类 @Sprin ...

  5. 学习微信小程序之css17clearfix原理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Android启动原理剖析

    我们知道Android是以一个Activity为单位的,可是我们并没有看到一个Activity是怎么開始启动的. 今天我 们就从Android的源码開始讲吧. ActivityThread: Andr ...

  7. iOS开发UI篇—程序启动原理和UIApplication

    iOS开发UI篇—程序启动原理和UIApplication   一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就 ...

  8. iOS开发UI篇—程序启动原理和UIApplication1

    iOS开发UI篇—程序启动原理和UIApplication   一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就 ...

  9. 【转】iOS开发UI篇—程序启动原理和UIApplication

    原文 http://www.cnblogs.com/wendingding/p/3766347.html   一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程 ...

随机推荐

  1. 四、Shell输入、输出功能和字符颜色设置

    一.Shell输入功能 1.键盘输入   方式一: [root@Salve four]# cat test.sh #!/bin/bash #-e 参数可以解析语句中的转义字符 echo -e &quo ...

  2. MySql类似Oracle的dual虚拟表

    在mysql里也存在和oracle里类似的dual虚拟表:官方声明纯粹是为了满足select ... from...这一习惯问题,mysql会忽略对该表的引用. 你可千万注意了: select * f ...

  3. 利用pg_stat_activity进行问题排查

    pg_stat_activity是一个非常有用的视图,可以帮助排查pg的一些问题(如连接数目过多问题).pg_stat_activity每行展示的是一个“process”的相关信息,这里的“proce ...

  4. MRDS学习二——机械车

    准备机械车: 第一步:从Service中选择一个Generic Differential Drive (通用差速驱动:同一轴的左右轮胎可以转动不同速度的车子)放入Diagram中. 第二步:对其进行配 ...

  5. PHP简单 对象(object) 与 数组(array) 的转换

    数组是PHP的灵魂,非常强大,但有时候面向对象编程也是挺方便的,数组 与 对象 之间切换也是常有的事: /** * 数组 转 对象 * * @param array $arr 数组 * @return ...

  6. 写JSP文件遇到的一个问题

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  7. JS表单验证-12个常用的JS表单验证

    JS表单验证-12个常用的JS表单验证 最近有个项目用到了表单验证,小编在项目完结后的这段时间把常用的JS表单验证demo整理了一下,和大家一起分享~~~ 1. 长度限制 <p>1. 长度 ...

  8. dataTables 使用小细节

    1.dataTables 日期查询 var row_content = []; //暂存表格的行内容 var rows=[]; //暂存表格行索引 /**将日期缓存添加,清除上一次日期搜索的缓存*/ ...

  9. VS2013 预定义的宏

    Visual Studio 2013 预定义的宏 https://msdn.microsoft.com/zh-cn/library/b0084kay(v=vs.120).aspx 列出预定义的 ANS ...

  10. robotframework----模板的使用

    模板只能放在测试用例里,可以测试大数据量,每一行模板的值,都做为用户关键字的输入参数,发下图: 删除特定证书2 的用户关键字如下: