文档章节

iOS深入学习:构建阶段、编译器错误和连接器错误

召唤攻城狮
 召唤攻城狮
发布于 2014/04/15 22:21
字数 1693
阅读 826
收藏 4

我建了一个iOS开发QQ交流群:188647173,大家可以一起来相互学习。

还有一个群里面大神的个人站点www.mylonly.com,大家有不会的可以向他请教。


Xcode会分步骤构建应用,这些步骤成为构建阶段,各个阶段所做的事情如下,

(1)编译源代码(Compile Sources):该阶段包含构建响应目标时需要编译的源代码。凡是加入项目中的源代码,默认都会加入该构建阶段。

(2)连接二进制文件和库(Link Binary with Libraries):完成代码的编译后,Xcode会将其和框架(库)连接,使代码能够使用相应框架中的类。

(3)拷贝程序包资源(Copy Bundle Resources):完成代码的编译和连接后,Xcode会生成一个可执行文件,并将其放入应用程序包(程序包其实是一个目录)。接着,Xcode会将拷贝程序包资源阶段中的文件加入程序包。这些资源是运行应用时需要使用的数据文件,例如ViewController.xib、图片和声音文件。这些都是应用程序的组成部分。凡是加入项目的非源代码文件,默认都会加入该构建阶段。

通常会在编译源代码的时候发现错误,连接二进制文件和库的阶段有时也会出错,如果了解各个阶段的作用,就可以更快地诊断和修正各个阶段产生的错误。

其实上述所说的三个过程,在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框架,就会出现连接错误的红色警告。


个人总结:这些编译过程方面的知识点很容易理解,但是往往被我们所忽视。所以在编码之余,拿出工具书看看理论讲解,肯定能够提高自己对于编码的理解。

© 著作权归作者所有

共有 人打赏支持
召唤攻城狮
粉丝 184
博文 53
码字总数 49671
作品 0
玉林
私信 提问
一样的iOS开发程序员为什么有人4k有人40k?

前言 移动开发真正火起来其实就是最近这几年,iOS 开发技术因为发展也就才这么几年,所以值得做的事情还有很多,这就造成了每年苹果的 WWDC 都会推出一堆新的特性和 API。整体上来说,这对业...

原来是泽镜啊
05/16
0
0
10个优秀Objective-C和iOS开发在线视频教程

如果你自己开发iOS应用,你肯定会发现网上有很多资源。学习编程的一个最好的方法就是自己写代码,而开始写代码的最快的方式就是看其他人怎么写。我们从海量视频和学习网站中整理出了我们认为...

mingxun
2014/05/09
0
0
学习如何针对iOS 7进行开发?

  iOS 7已经发布了六个测试版,除了beta 6进行了小幅修正外,其他几个测试版都有不小的改动。昨天有消息说苹果将在9月10日发布iOS 7正式版,那么GM版很快将会与开发者见面。在iOS 7来临前夕...

fangzhou99
2013/09/17
0
0
转:一套代码iOS、Android两端运行,Google Flutter意味着什么?

原文:https://www.toutiao.com/a6569388465538990600/?ttfrom=weixin&utmcampaign=clientshare×tamp=1529580533&app=newsarticle&utmsource=weixin&iid=35476649324&utmmedium=toutiao......

鸿蒙无上至尊
06/22
0
0
移动应用和游戏开发两个阶段在线视频培训的未来计划

在51CTO学院开线上视频课程已经3个多月了,也上了不少课。不过发现还有很多课没有开。现在就将未来的开课计划公布一下。计划分为两个阶段。第一阶段主要是Cocos2d-x和Cocos2d-js的游戏开发培...

androidguy
06/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

腾讯与Github的魔幻会面背后的故事…

10月22日,腾讯开源管理办公室有幸邀请到Github新晋CEO Nat Friedman,前来鹅厂参观交流。目前腾讯已经有近70个项目在Github上开源,共获得17w stars,世界排名11位。Github是腾讯开源的主阵...

腾讯开源
25分钟前
1
0
单例模式

单例模式(Singleton pattern)属于创建型设计模式。 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对...

NinjaFrog
30分钟前
1
0
TypeScript基础入门之装饰器(三)

转载 TypeScript基础入门之装饰器(三) 继续上篇文章[TypeScript基础入门之装饰器(二)] 访问器装饰器 Accessor Decorator在访问器声明之前声明。 访问器装饰器应用于访问器的属性描述符,可用...

durban
48分钟前
2
0
spring5调研学习(转载)

Spring框架的新功能 这一章主要提供Spring框架新的功能和变更。 升级到新版本的框架可以参考。Spring git。 内容列表 Spring 5.x框架新的功能 Spring 4.x框架新的功能 Spring 3.x框架新的功能...

小海bug
58分钟前
2
0
为何Spring框架能这么流行?

想要学习更多关于Spring框架在Java开发者中如此流行?看这篇文章可以学到更多! Spring框架特性 Spring是用于应用开发中的一款强大,轻量级框架。更广泛地说,你可以认为Spring框架是一个定义...

java知识分子
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部