duplicate symbol错误

问题:项目中今天引入第三方库报错,报错如下图:

Snip20170609_1.png

解决办法:错误显示是duplicate symbol,于是前往项目Build Settings -> Other Linker Flags中删除掉之前添加的 -all_load,项目恢复正常。

Xcode中Other Linker Flags的作用:

  • 在iOS开发中,引入第三方的一些静态库,导入后第三方库就会出现类似的问题,一般的第三方库的开发文档中都会写出这种问题的解决办法,如在 Other Linker Flags中加入 -Objc或者-all_load或者-force_load这样的解决方法,为什么要这么做呢?首先引入一个连接器的概念。
    链接器:又译为链接器、连接器,是一个程序,将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可执行文件,如C代码到可执行文件经历的步骤是:
    源代码 -> 预处理器 -> 编译器 -> 汇编器 -> 机器码 ->链接器 -> 可执行文件

在最后一步需要把 .o 文件和 C 语言运行库链接起来,这时候需要用到 ld 命令。源文件经过一系列处理以后,会生成对应的 .obj 文件,然后一个项目必然会有许多 .obj 文件,并且这些文件之间会有各种联系。链接器就是把这些目标文件和所用的一些库链接在一起形成一个完整的可执行文件。
那么,Other Linker Flags 设置的值实际上就是 ld 命令执行时后面所加的参数。
苹果官方的一段话:
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.

那么,Other Linker Flags 设置的值实际上就是 ld 命令执行时后面所加的参数

  • -Objc:一般这个参数足够解决前面提到的问题,这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大,因为加载了很多不必要的文件而导致可执行文件变大。但是如果静态库中有类和category的话只有加入这个flag才行,但是Objc也不是万能的,当静态库中只有分类而没有类的时候,Objc就失效了,这就需要使用-all_load或者-force_load了。

  • -all_load: 会强制链接器把目标文件都加载进来,即使没有objc代码。但是这个参数也有一个弊端,那就是你使用了不止一个静态库文件,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件 这里会有两种方法解决 1:用命令行就行拆包. 2:就是用下面的这个参数

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

你可能感兴趣的:(duplicate symbol错误)