我建了一个iOS开发QQ交流群:188647173,你们能够一块儿来相互学习。框架
还有一个群里面大神的我的站点www.mylonly.com,你们有不会的能够向他请教。工具
Xcode会分步骤构建应用,这些步骤成为构建阶段,各个阶段所作的事情以下,学习
(1)编译源代码(Compile Sources):该阶段包含构建响应目标时须要编译的源代码。凡是加入项目中的源代码,默认都会加入该构建阶段。ui
(2)链接二进制文件和库(Link Binary with Libraries):完成代码的编译后,Xcode会将其和框架(库)链接,使代码可以使用相应框架中的类。编码
(3)拷贝程序包资源(Copy Bundle Resources):完成代码的编译和链接后,Xcode会生成一个可执行文件,并将其放入应用程序包(程序包实际上是一个目录)。接着,Xcode会将拷贝程序包资源阶段中的文件加入程序包。这些资源是运行应用时须要使用的数据文件,例如ViewController.xib、图片和声音文件。这些都是应用程序的组成部分。凡是加入项目的非源代码文件,默认都会加入该构建阶段。spa
一般会在编译源代码的时候发现错误,链接二进制文件和库的阶段有时也会出错,若是了解各个阶段的做用,就能够更快地诊断和修正各个阶段产生的错误。code
其实上述所说的三个过程,在Xcode中有所展现,可能咱们都不知道罢了,项目配置文件->Build Phrases,以下图,接口
PS:“0依赖关系”这涉及到包依赖关系,我leader跟我说他最自豪的就是对于“包依赖关系”的掌控,这方面我还不是特别了解,还要多多学习。图片
下面主要说下编译阶段和链接阶段,资源
编译阶段--------预处理和编译
编译源代码分为两个步骤:预处理和编译。
预处理:预处理的做用是为每一个实现文件(.m)建立一个中间文件(intermediate file)。中间文件和实现文件同样,都是Objective-C代码,可是中间文件的体积可能会很大。
预处理器(preprocessor)处理完实现文件中的所有预处理指令后,会生成一个中间文件。与处理指令四大有哎#的语句,例如#import、#define。。。,预处理器在处理#import语句时,会将该语句天换成导入文件的内容。例如ViewController.m文件中包含ViewController.h文件,ViewController.m生成的中间文件会包含ViewController.h和ViewController.m的所有代码。不只如此,ViewController.h文件中还可能包含UIKit.h和CoreLocation.h,这两个文件会导入更多的文件,导入的文件再导入其余文件,以此类推,ViewController.m的中间文件是这些文件的代码的集合。
可能有的童鞋没有明白为何预处理是在编译代码以前,我经过代码来讲明一下吧,咱们经过#define定义一个常量Debug,而后在#if~#elif~#endif中使用Debug常量,固然这里的#if~#elif~#endif要在大括号{}中使用,例如将#if~#elif~#endif写在-(viod)viewDidLoad{...}中,
#define Debug 0
#if Debug
NSLog(@"Debug is 0");
#elif
NSLog(@"Debug is not 0");
#endif
咱们在Xcode中看这段代码的效果,以下图,
你们看出上面图片中NSLog颜色的不一样吗?此时Debug为0,因此#if Debug后面的代码不会在编译的时候被编译,#else后面的代码会在编译的时候被编译,上面的代码也说明在预处理阶段,就肯定了哪些代码会被编译。因此说预编译阶段就是在编译以前。
编译:预处理完成后,Xcode会编译以前生成的中间文件。Objective-C代码会被转换成机器码,保存在目标文件中(object file)。一个目标文件对应一个中间文件。在应用开发阶段,大部分错误会发生在这个将代码转换成机器码的编译阶段,编译器“看不懂”代码时会报错,这些在编译阶段产生的错误成为编译时错误(compile-time errors)或语法错误(syntax errors)。
常见的编译错误有放错分号的位置、方括号([])或花括号({})不匹配、拼写错误或字母大小写错误等。使用未声明的类也会致使此类错误发生,例如注释掉#import "CoreLocation.h",这时候ViewController.m的中间文件包括来自CoreLocation.h的代码,其中包括CLLOcationManager的接口声明和CLLocationManagerDelegate的协议声明,没有相应的导入语句,这些文件就不会成为所生成的中间文件的一部分,编译器也就没法处理相关的代码。
链接阶段:目标文件会包含(在实现文件中实现的)方法的机器码。可是某个实现文件可能hi用到其余实现文件的代码,例如Appdelegate.m会使用到startUpdatingLocation方法,该方法的机器码保存在CLLocationManger.m的目标文件中。编译器不会将startUpdatingLocation方法的代码拷贝至Appdelegate.m的目标文件中,而是设置一个链接,指向CLLocationManager.m的目标文件。链接二进制文件和库就是处理这类链接的阶段,该阶段简称为链接阶段。
例如将Core Location框架和目标链接起来。框架是一组类的集合,类由两个文件定义:头文件和实现文件。框架的实现文件是已经预编译好的,而且框架回家创立后的目标文件分红一个或多个库文件(因此Objective-C的框架没有实现文件,相应地文件已转成机器码)。凡是用到Core Location框架代码的类,编译器都会在其目标文件中放置相应地链接,指向Core Location库。
若是编译器没法处理某个链接(例如没法找到包含相应代码的目标文件,或是目标文件没有包含被引用的代码),就会产生链接错误。例如在使用Core Location中的类时候没有引入CoreLocation.framework框架,就会出现链接错误的红色警告。
我的总结:这些编译过程方面的知识点很容易理解,可是每每被咱们所忽视。因此在编码之余,拿出工具书看看理论讲解,确定可以提升本身对于编码的理解。