iOS静态库遇到的坑

问题:

  • iOS开发中我们经常会遇到这种错误Undefined symbols for architecture arm64 这个错误表示工程某些地方不支持arm64指令集。而这个问题基本上是由于引入了他人的静态库

问题分析:

  • 对于iOS设备来说iOS的指令集有armv6、armv7、armv7s、arm64 这样四种,不同型号的iOS设备使用不同的指令集,下面是各自的区别:

armv6

  • iPhone、iPhone 3G
  • iPod 1G、iPod 2G

armv7

  • iPhone 3GS、iPhone 4
  • iPod 3G、iPod 4G、iPod 5G
  • iPad、iPad 2、iPad 3、iPad Mini

armv7s

  • iPhone 5、iPhone 5C
  • iPad 4

arm64

  • iPhone 5S iPhone 6 iPhone 6Plus
  • iPad Air, Retina iPad Mini

问题解决:

1.检查一下静态库的配置路径是否正确

Build Settings>Search Paths>Library Search Path(一定要认真检查)

2.查看了静态库所支持的架构

打开终端输入查看命令lipo - info xxx.a ,结果如下:


iOS静态库遇到的坑_第1张图片
lipo.png
3.检查一下Architectures的配置

Architectures:该编译选项指定了工程将被编译成支持哪些指令集,支持指令集是通过编译生成对应的二进制数据包实现的,如果支持的指令集数目有多个,就会编译出包含多个指令集代码的数据包,造成最终编译的包很大。
Build Active Architectures Only:当该选项设置成YES时,你连上一个armv7指令集的设备,就算你的Valid Architectures和Architectures都设置成armv7/armv7s/arm64,还是依然只会生成一个armv7指令集的二进制包。通常情况下,该编译选项在Debug模式都设成YES,Release模式都设成NO。
Valid Architectures:该编译项指定可能支持的指令集,该列表和Architectures列表的交集,将是Xcode最终生成二进制包所支持的指令集。
注意:1、指令集是向下兼容的。比如,armv7s指令集的设备,可以兼容运行使用armv7、armv6编译的程序。可以根据自己需要配置。

4.设置编译参数

Build Settings -> Linking -> Other Linker Flags
添加对应的库文件:-lAPayLib

注:
1.前面加横杠’-‘,l,编译的时候xcode默认会自动把库名加上lib前缀。
2.如果静态库有category,那么需要添加-ObjC参数标识,否则可能会报:unrecognized selector sent to instance
3.参数说明引用

  • -ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中
  • -all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。
  • -force_load:所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载 
    4.编译方式引用
    静态库中采用ObjectC++实现,因此需要您保证您工程中至少有一个.mm后缀的源文件(您可以将任意一个.m后缀的文件改名为.mm),或者在工程属性中指定编译方式,即将XCode的Project -> Edit Active Target -> Build -> GCC4.2 - Language -> Compile Sources As设置为"Objective-C++"

参考:http://www.cnblogs.com/bomo/p/4760791.html

你可能感兴趣的:(iOS静态库遇到的坑)