Xcode中other linker flags的作用

-force_load这个参数今天被问到了却因为很少见到,没有答上,感到深深的羞愧,于是把查到的文章转到自己的博客里,随时查看加深下记忆
参考文章:http://blog.csdn.net/meegomeego/article/details/19343423

链接器

Targets选项下有Other linker flags( 链接器 )的设置,用来填写XCode的链接器参数,说白了,就是ld命令除了默认参数外的其他参数。ld命令实现的是链接器的工作,详细说明可以在终端man ld查看。如:-ObjC -all_load -force_load等。在 iOS 开发过程中,有时候会用到第三方的静态库(.a文件),然后导入后发现编译正常但运行时会出现 selector not recognized 的错误,从而导致app闪退。接着仔细阅读库文件的说明文档,你可能会在文档中发现诸如在 Other Linker Flags 中加入 -ObjC 或者 -all_load 这样的解决方法。

一个程序从简单易读的代码到可执行文件往往要经历以下步骤:

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

在最后一步需要把.o文件和C语言运行库链接起来,这时候需要用到ld命令。源文件经过一系列处理以后,会生成对应的.obj文件,然后一个项目必然会有许多.obj文件,并且这些文件之间会有各种各样的联系,例如函数调用。链接器做的事就是把这些目标文件和所用的一些库链接在一起形成一个完整的可执行文件。那么,Other linker flags设置的值实际上就是ld命令执行时后面所加的参数。
如果要详细研究链接器做了什么,请看:http://www.dutor.net/index.php/2012/02/what-linkers-do/

为什么会闪退

苹果官方Q&A上有这么一段话:

The "selector not recognized" runtime exception occurs due to an issue between the implementation of standard UNIX static libraries, the linker and the dynamic nature of Objective-C. Objective-C does not define linker symbols for each function (or method, in Objective-C) - instead, linker symbols are only generated for each class. If you extend a pre-existing class with categories, the linker does not know to associate the object code of the core class implementation and the category implementation. This prevents objects created in the resulting application from responding to a selector that is defined in the category.

翻译过来,大概意思就是Objective-C的链接器并不会为每个方法建立符号表,而是仅仅为类建立了符号表。这样的话,如果静态库中定义了已存在的一个类的分类,链接器就会以为这个类已经存在,不会把分类和核心类的代码合起来。这样的话,在最后的可执行文件中,就会缺少分类里的代码,这样函数调用就失败了。

解决方法

解决方法在背景那块我就提到了,就是在Other Linker Flags里加上所需的参数,用到的参数一般有以下3个:

  • -ObjC
  • -all_load
  • -force_load

下面来说说每个参数存在的意义和具体做的事情。

-ObjC 加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中,虽然这样可能会因为加载了很多不必要的文件而导致可执行文件变大,但是这个参数很好地解决了我们所遇到的问题。但是当静态库中只有分类而没有类的时候,-ObjC参数就会失效了。这时候,就需要使用-all_load或者-force_load了。

-all_load会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。

-force_load所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。

关于这个-force_load东东,没想到我刚说少见到就遇到了这个问题尴尬今天又重写了demo,于是呢于是.......

遇到了-ObjC冲突,如果项目中使用-ObjC有冲突,可以添加-force_load来解决






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值