链接器

首先,要说明一下Other Linker Flags到底是用来干嘛的。说白了,就是ld命令除了默认参数外的其他参数。ld命令实现的是链接器的工作,详细说明可以在终端man ld查看。

如果有人不清楚链接器是什么东西的话,我可以作个简单的说明。

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

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

源文件经过一系列处理以后,会生成对应的.obj文件,然后一个项目必然会有许多.obj文件,并且这些文件之间会有各种各样的联系,例如函数调用。链接器做的事就是把这些目标文件和所用的一些库链接在一起形成一个完整的可执行文件。

可能我描述的比较肤浅,因为我自己了解的也不是很深,建议大家读一下这篇文章,可以对链接器做的事情有个大概的了解:链接器做了什么

为什么会闪退

苹果官方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,一般这个参数足够解决前面提到的问题,苹果官方说明如下:

This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.

简单说来,加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中,虽然这样可能会因为加载了很多不必要的文件而导致可执行文件变大,但是这个参数很好地解决了我们所遇到的问题。但是事实真的是这样的吗?

如果-ObjC参数真的这么有效,那么事情就会简单多了。

Important: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -allload or -forceload flags.

当静态库中只有分类而没有类的时候,-ObjC参数就会失效了。这时候,就需要使用-all_load或者-force_load了。

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

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

【转】关于Xcode的Other Linker Flags的更多相关文章

  1. 关于Xcode的Other Linker Flags

    背景 在ios开发过程中,有时候会用到第三方的静态库(.a文件),然后导入后发现编译正常但运行时会出现selector not recognized的错误,从而导致app闪退.接着仔细阅读库文件的说明 ...

  2. xcode:关于Other Linker Flags

    一.关于Other Linker Flags xcode中,在“Targets”选项下有Other Linker Flags选项,在这里可以填写xcode链接器的参数,如:-ObjC.-all_loa ...

  3. iOS 关于Xcode上的Other linker flags

    Targets选项下有Other linker flags的设置,用来填写XCode的链接器参数,如:-ObjC -all_load -force_load等.还记得我们在学习C程序的时候,从C代码到 ...

  4. 关于Xcode上的Other linker flags

    Targets选项下有Other linker flags的设置,用来填写XCode的链接器参数,如:-ObjC -all_load -force_load等.还记得我们在学习C程序的时候,从C代码到 ...

  5. iOS关于Xcode上的Other linker flags

    Targets选项下有Other linker flags的设置,用来填写XCode的链接器参数,如:-ObjC -all_load -force_load等.还记得我们在学习C程序的时候,从C代码到 ...

  6. Xcode 编辑器之关于Other Linker Flags相关问题

    一,概述 问题场景一 当从网上去下载一些之前的完整的项目的时候,用终端也 pod update了,但一运行,熟悉的linker错误就出来了. 解决办法 在Other Linker Flags(也即 O ...

  7. Xcode出现( linker command failed with exit code 1)错误总结

    这种问题,通常出现在添加第三方库文件或者多人开发时. 这种问题一般是找不到文件而导致的链接错误. 我们可以从如下几个方面着手排查. 先可以再试试一下几个方法:  1,看看是不是有新添加的文件跟之前文件 ...

  8. -other linker flags - 详解

    • 值:-objC,-all_load,-force_load

 • -objC: 在iOS 中,使用-all_load时,如果静态库中有类别时会出问题,使用其他两个值则不会有问题.

 • -al ...

  9. Other Linker Flags到底是什么

    一.问题描述 在项目开发中用到百度地图,有时候在工程中会报“方法找不到”的错误(unrecognized selector sent to instance). 二.问题分析 首先,要说明一下Othe ...

随机推荐

  1. C/c++输入输出函数

    最全输入函数 c/c++一:c=getchar();功能:读入一个字符说明:调用此函数时要求在程序的第一行有预编译命令:#include<stdio>,不过在做c++时 有#include ...

  2. inline-block在ie6中的经典bug

    众所周知,给元素设置 inline-block ,可以让ie下的元素出发layout:1. 但是,当给元素设置 inline-block 后,在另外一个class 样式(非设置inline-block ...

  3. MyEclipse中使用JUnit进行单元测试

    1. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJUnit,代码如下,注意需要先建packag ...

  4. Codeforces Round #207 (Div. 1)B(数学)

    数学so奇妙.. 这题肯定会有一个循环节 就是最小公倍数 对于公倍数内的相同的数的判断 就要借助最大公约数了 想想可以想明白 #include <iostream> #include< ...

  5. JQuery Ajax 在asp.net中使用小结

    自从有了JQuery,Ajax的使用变的越来越方便了,但是使用中还是会或多或少的出现一些让人短时间内痛苦的问题.本文暂时总结一些在使用JQuery Ajax中应该注意的问题,如有不恰当或者不完善的地方 ...

  6. codevs 1088 神经网络

    bfs.语文题. #include<iostream> #include<cstdio> #include<cstring> #include<algorit ...

  7. 最简单的视音频播放示例6:OpenGL播放YUV420P(通过Texture,使用Shader)

    本文记录OpenGL播放视频的技术.上一篇文章中,介绍了一种简单的使用OpenGL显示视频的方式.但是那还不是OpenGL显示视频技术的精髓.和Direct3D一样,OpenGL更好的显示视频的方式也 ...

  8. win32 摄像头捕获系统vfw

    //win32 摄像头捕获系统vfw //  VideoRecord.h ///  用于定义一些资源ID #include "resource.h" //#define EXIT  ...

  9. [转] C#中发送消息给指定的窗口,以及接收消息

    原文C#中发送消息给指定的窗口,以及接收消息 public class Note { //声明 API 函数 [DllImport("User32.dll", EntryPoint ...

  10. 基于Fragment实现Tab的切换,滑出侧边栏

    最近在学习Fragment(碎片)这是android3.0以后提出的概念,很多pad上面的设置部分都是通过Fragment来实现的,先看看具体的效果吧(图一)  (图二) (图三)第一章图片是初始时的 ...