问题
在ios开发过程中,有时候会用到第三方的静态库(.a文件),然后导入后发现编译正常但经常有运行时会出现多种类型的错误,从而导致程序闪退。
可能的解决方案
解决上述问题的一种极有可能的解决方案是修改工程Build Settings选项卡Linking命令组中Other linker flags,如图所示。
Linking命令组中Other linker flags
在Other Linker Flags
里加的参数主要有如下三个:
-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
需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。
参考:
1.http://www.cnblogs.com/robinkey/archive/2013/05/27/3101095.html
2.http://my.oschina.net/ffs/blog/372850
3.http://my.oschina.net/u/728866/blog/194741