关于编译的时候link参数
代码由源码到可执行文件的过程,简单的说分为四个步骤
- 预处理
- 编译
- 汇编
- 链接
这几步过程通常由我们的IDE也就是Xcode帮我们悄悄的完成了,但是有时候我们也会遇到一些问题,需要我们自己指定某些参数来完成.
今天主要说一下Xcode BuildSetting 中的Other Link Flags 参数,这个参数顾名思义是link的时候指定的参数
If you're seeing a "selector not recognized" runtime exception when calling a category method that is implemented in a static library, you are hitting the link-time build issue described here, and need to add the -ObjC linker flag to your project.
A UNIX static library is just a collection of object files. Normally the linker only pulls in an object file from a static library if doing so would resolve some undefined symbol. Not pulling in all object files reduces the size of the final executable.
The dynamic nature of Objective-C complicates things slightly. Because the code that implements a method is not determined until the method is actually called, Objective-C does not define linker symbols for methods. Linker symbols are only defined for classes
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.
静态库本质上就是一系列的目标文件的集合,通常linker会从静态库里加载这些目标文件.
因为OC是动态语言,所以OC没有为每个方法建立符号表,而是为每个类建立链接符号。这样的话静态库中定义了已存在的类的分类,链接器就以为这个类存在了,不会将分类和核心类代码关联(合并)起来.
这个时候就需要我们自己手动指定link参数了
Other Link Flags :
-ObjC:这个链接参数,是针对OC的,这个参数会在link的时候将静态库的所有的OC的类和分类全部链接到可执行文件中
-all_load : 这个链接参数,会让linker从它能扫描到的静态库内加载所有的目标文件
-force_load : 强制link链接某个指定的库,需要指定库的路径.例如 : -force_load $(PROJECT_DIR)/yourframewokname.framework/yourframeworkname
一般我们开发的时候默认使用-ObjC的链接参数,不过当你有某个静态库,这个静态库内包含了某个不包含任何OC的代码文件的时候,这个静态库的这个文件可能不会被链接到可执行文件内.你可以这些个链接参数来更改这个行为.
PS: 不推荐使用-all_load这个链接参数,因为这样会使你的可执行文件体积变大.而且可能会引起符号冲突问题.
推荐使用-force_load的方式.不过我们还有一个更加取巧的方法,你可以在这个文件内声明一个空的OC类,这样-ObjC参数就会去link这个类了.
网友评论