iOS 知识点安全编译原理

Other Linker Flags

2018-08-22  本文已影响26人  GX_Dust

Other Linker Flags到底是用来干嘛的?

源代码 > 预处理器 > 编译器 > 汇编器 > 机器码 > 链接器 > 可执行文件

为什么我们调用静态库的方法时候会闪退

UNIX静态库及C程序链接过程:

当一个C语言程序编译时,所有源码会编译为对象文件,即.o文件(object file)。这些对象文件中包含了可执行程序和静态数据。链接器最终将所有文件组合到一起, 产生最终的可执行文件。
一个源文件引用了定义在其他文件中的一些东西时(一个方法),一个 undefined symbol 就写入了它所产生的object 文件中,等待最终被解释掉。在最终构建可执行文件的时,链接器将包含这些undefined symbols的object文件中拉取信息, 解决掉被标记的undefined symbols。
一个UNIX的静态库其实就是一系统object file的集合,一般情况下, 它只会拉取它需要的文件。好处是减小最终可执行文件的大小。

举个例子

比如main.c使用一个函数,名叫foo( ),而这个函数定义myMain.c里面。在生成.o文件的时候,main.o就会有一个foo( )undefined symbols标记。链接期间,myMain.o便会被打入最终的可执行文件中。但是,假如还有一个heMain.c文件,但是里面的函数没被使用,那这个heMain.o文件便不会出现最后的可执行文件中。

Objective-C链接过程有什么不同?

oc是动态性语言,对象方法的实现只有到被调用时候才被确定。基于这个原因,Objective-C没有方法级别定义符号,只有类级别定义符号。

举个例子

main.c中包含以下代码: [[FooClass alloc] initWithBar:nil]; 那么在链接的时候,main.o文件就会生成一个未定义符号如:(Undefined Symbols) FooClass,但不会定义initWithBar方法的符号。

坑在哪?

Category只是一个类的分类

解决方法

在Other Linker Flags里加上所需的参数,用到的参数一般有以下3个:
-ObjC
-all_load
-force_load

重要提示: 对于64位和iPhone OS应用程序,当静态库只包含类别,没有类, 会存在一个链接器bug,它阻止-ObjC从静态库加载对象文件

重要提示: 假如你使用了不止一个静态库文件,那么很可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件

上一篇下一篇

猜你喜欢

热点阅读