本文转自:http://www.cnblogs.com/oc-bowen/p/6061261.html

     http://www.cnblogs.com/oc-bowen/p/6061178.html

一. iOS中常见文件

(一). Xcode6之前

  1. 创建项目,默认可以看见一个存放框架的文件夹
  2. info文件以工程文件名开头,如:第一个项目-Info.plist
  3. 项目中默认有一个PCH文件

(二). Xcode6之后(包括Xcode6)

  1. 创建项目,没有框架文件夹,使用时系统才去加载
  2. info文件不以工程文件名开头,如:Info.plist
  3. 项目中没有PCH文件

(三). Info.plist文件(项目配置文件)

  1. 作用:保存应用的信息,软件名称、版本号等等,相当于身份证
  2. Bundle name:程序名称,不能超过12个字节
  3. Bundle versions string, short:APP版本号
  4. Bundle identifier:APP项目唯一标识
  5. Bundle version:内部开发人员使用的版本号
  6. Main storyboard file base name:第一启动的storyboard文件
  7. 注意:图形化的Info.plist文件上面的KEY不是真实的KEY,要想看真实的KEY得看Info.plist文件的源码 
    操作:Info.plist(选中后右键单击) -> Open As -> Source Code
  8. 代码查看版本号
  NSDictionary *dicInfo = [NSBundle mainBundle].infoDictionary;
NSLog(@"%@",dicInfo[@"CFBundleShortVersionString"]);

(四). PCH文件

PCH文件是一个头文件,能被项目中的其他所有源文件共享和访问

1. PCH文件的需求

一个宏或头文件等,很多文件都需要用到,怎么解决,搞个公用的头文件,同时导入这个头文件

2. 作用

(1). 存放一些公用的宏 
(2). 存放一些公用头文件 
(3). 管理日志的输出,自定义Log

3. 为什么要管理日志输出

因为日志输出非常耗性能,一般发布的时候不需要日志输出,只有调试的时候才需要

/*
...表示能接收任何参数
__VA_ARGS__ 表示左边...的参数会替代到右边NSLog中
*/
#ifdef DEBUG // 调试阶段
#define HMLog(...) NSLog(__VA_ARGS__)
#else // 发布阶段
#define HMLog(...)
#endif

5. 注意

二. 程序的启动原理

(一). 程序的启动过程

  1. 打开程序
  2. 执行main函数
  3. 结束程序

(二). 执行main函数

int main(int argc, char * argv[]) {
@autoreleasepool {
// 第三个参数为nil时,默认是UIApplication类名
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

1. UIApplicationMain函数的原型

UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

2. UIApplicationMain的底层实现

(1). 根据principalClassName提供的类名,创建一个UIApplication对象

(2). 根据delegateClassName提供的类名,创建一个UIApplication的代理对象

(3). 开启一个主运行循环,它是保持程序一直在运行,并处理事件

(4). 加载Info.plist和启动图片,并且判断Info.plis有没有指定Main.storyboard,如果指定,就去加载

3. application隐藏状态栏

4. 补充:反射机制

反射机制好处:如果类名用字符串表示,即使类名写错,编译器不报错;如果通过反射机制,类名写错,编译器报错

NSString *className =  NSStringFromClass([AppDelegate class]);
Class strClass = NSClassFromString(@"AppDelegate");

(三). 加载Main.storyboard

1. 加载Main.storyboard步骤

2. 窗口(UIWindow)

3. 补充

4. addSubView和rootViewController的区别

5. makeKeyAndVisible方法底层所做的事情

6. 窗口的层级

7. 代码模仿storyboard的加载

注:要习惯代码创建窗口和控制器,因为开发中很少用到storyboard直接开发,老项目中没有storyboard

  // 创建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // 加载storyboard
// Main.storyboard文件名不用写后缀
// 当写nil时,系统默认[NSBundle mainBundle]
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; //创建控制器
//方式1:代码创建控制器
//UIViewController *vc = [[UIViewController alloc] init];
//vc.view.backgroundColor = [UIColor whiteColor]; //方式2:加载storyboard里面有箭头的控制器
//UIViewController *vc = [storyboard instantiateInitialViewController];
// 当加载storyboard里面的控制器,控制器所属哪个类,就是创建哪个类
//NSLog(@"%@",NSStringFromClass([vc class])); //方式3:storyboard里面有多个控制器,加载对应标识的控制器
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"B"]; //创建窗口的根控制器
self.window.rootViewController = vc; // 显示窗口
[self.window makeKeyAndVisible];

(四). 通过XIB创建控制器的view

1. 步骤

a. 创建一个控制器的类

b. 创建一个xib,并指定xib所描述的控制器,一个xib只能用来描述一个控制器,如果没有指定,就不能拖线指定控制器的view

注意:xib里可以有多个UIView,不能固定死 
iOS应用的执行原理-LMLPHP


c. 拖线指定xib中哪个UIView是控制器的view

选中File`s Owner,右键单击后,在弹出的对话框上拖线 
iOS应用的执行原理-LMLPHP


iOS应用的执行原理-LMLPHP


d. 代码加载xib中描述控制器的view

  //创建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // 方式一:明确initWithNibName:方法的两个参数
//UIViewController *vc = [[ViewController alloc] initWithNibName:@"View" bundle:[NSBundle mainBundle]];
// 方式二:initWithNibName:方法的两个参数,只明确第一个参数,省略第二个参数
// bundle写nil时,系统默认[NSBundle mainBundle]
//UIViewController *vc = [[ViewController alloc] initWithNibName:@"View" bundle:nil];
// 方式三:initWithNibName:方法的两个参数都省略
//UIViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
// 方式四:调用init方法
UIViewController *vc = [[ViewController alloc] init]; // 设置窗口的根控制器
self.window.rootViewController = vc; // 设置程序的主窗口并显示窗口
[self.window makeKeyAndVisible];

2. 注意

只有控制器的init方法,底层才会调用initWithNibName:bundle:方法

3. view的创建

iOS应用的执行原理-LMLPHP

4. 控制器的loadView方法

5. xib和storyboard的区别

storyboard已经指定了控制器的view,不需要我们管,xib需要我们手动管理

6. 如何快速生成一个xib描述控制器的view

  1. 定义新的控制器的时候,勾选xib,会自动搞一个xib描述控制器的view
  2. 会自动生成一个和控制器同名的xib,并且里面设置好了

(五). 控制器的View

1. view的生命周期

只要是View开头的都是View的生命周期方法 
iOS应用的执行原理-LMLPHP

2. 内存警告处理

iOS应用的执行原理-LMLPHP

a. 处理过程

有内存警告 -> 调用didReceiveMemoryWarning方法 -> 判断控制器的View存不存在 -> 存在就判断能不能被释放(判断是不是正在显示在界面上) -> 能释放就调用ViewWillUnload -> 完全释放后就调用ViewDidUnload

b. 注意

内存警告处理时,ViewWillUnload和ViewDidUnload不一定被调用,因为这是系统自动判断的

05-28 14:11