1. 静态库中包含 “分类”

有时候,在静态库中,也是用了一些 Foundation 的分类,比如 UIImage+Clip 等。
此时需要前往:Build Settings->Other Linker Flags->-ObjC 或者-all_load
注意:是 -ObjC,而不是 -Objc

Other Linker Flags

三个参数:

符号 说明
-ObjC 链接器会把静态库中所有的 Objective-C 类和分类都加载到最后的可执行文件中
-all_load 链接器会把所有找到的目标文件都加载到可执行文件中,但千万不要注意,假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到 ld: duplicate symbol 错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到 - ObjC 失效的情况下使用 - force_load 参数。
-force_load 所做的事情跟 - all_load 其实是一样的,但是 - force_load 需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载

2. Deployment Target

注意静态库的使用环境,在什么设备上使用,支持最低什么系统版本等等。
Targeted Device Family1iPhone2iPad
iOS Deployment Target:支持的最低 iOS 系统版本
image.png

3. arm 多架构编译

a . 编译出错

首先了解苹果移动设备均采用 arm 架构的 CPU,而 Mac 则是 Inter 的 CPU。
假如入你在使用编译库中遇到报错:

  • 在真机上编译报错:

No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).

  • 在模拟器上编译报错:

No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv7s, VALID_ARCHS=armv7 armv6).
这个错,就是在编译静态库时没有配置正确的编译器指令造成的,此时需要设置正确的架构。

b. 设备指令集

针对苹果移动设备,都采用 arm 处理器的指令集,这些指令集都是向下兼容的,例如 armv7 指令集兼容 armv6,只是使用 armv6 的时候无法发挥出其性能,无法使用 armv7 的新特性,从而会导致程序执行效率没那么高。
还有两个我们也很熟悉的指令集:i386|x86_64 是 Mac 处理器的指令集,i386 是针对 intel 通用微处理器 32 架构的。x86_64 是针对 x86 架构的 64 位处理器。所以当使用 iOS 模拟器的时候会遇到 i386|x86_64,iOS 模拟器没有 arm 指令集。
此时一般需要合并静态库,以支持多指令集。

指令集 设备 说明
armv6 iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch
armv7 iPhone3GS, iPhone4, iPhone4S
iPad, iPad2, iPad3(The New iPad), iPad mini
iPod Touch 3G, iPod Touch4
armv7s iPhone5, iPhone5C
iPad4(iPad with Retina Display)
arm64/armv8 iPhone5S 及之后 iPhone
iPad Air, iPad mini2(iPad mini with Retina Display)

c. Xcode 编译选项

针对架构及编译指令集,Xcode 提供了一下选项:

Xcode 设置项 定义 注意事项
Architectures 要支持的指令集 该选项指定了工程将被编译成支持哪些指令集。如果支持的指令集数目有多个,就会编译出包含多个指令集代码的数据包,从而会造成最终编译生成的包很大。
Valid Architectures 指即将编译的指令集 该选项指定可能支持的指令集,该 Valid architectures 列表和 Architectures 列表的交集,将是 Xcode 最终生成二进制包所支持的指令集。限制可能被支持的指令集的范围。
例如:Valid Architectures 设置的支持 arm 指令集有:armv7/armv7s/arm64,对应的 Architectures 设置的支持 arm 指令集有:armv7s,这时 Xcode 只会生成一个 armv7s 指令集的二进制包
Build Active Architecture Only 该编译项用于设置是否只编译当前使用的设备对应的 arm 指令集。 Xcode 中设置:
①设置为 Yes, 编译速度更快,只编译当前的 architecture 版本
②设置为 No,编译速度更慢会编译所有的版本
例如:
当该选项设置成 YES 时,你连上一个 armv7 指令集的设备 (iPhone5、5c),就算你的 Valid Architectures 和 Architectures 都设置成 armv7/armv7s/arm64,还是依然只会生成一个 armv7 指令集的二进制包。

4. Bitcode 支持

5. 避免重复引入

ld: 2 duplicate symbols for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

记住要给自己的库加上前缀,避免与其他第三方库,引用冲突。

6. 版本号如何制定

When to Use Major Versions

You should make a new major version of a framework or dynamic shared library whenever you make changes that might break programs linked to it. The following changes might cause programs to break:

  • Removing public interfaces, such as a class, function, method, or structure
  • Renaming any public interfaces
  • Changing the data layout of a structure
  • Adding, changing, or reordering the instance variables of a class
  • Adding virtual methods to a C++ class
  • Reordering the virtual methods of a C++ class
  • Changing C++ compilers or compiler versions
  • Changing the signature of a public function or method

    When to Use Minor Versions

    You should update the version information of your framework when you make any of the following changes:

  • Add a class

  • Add methods to an Objective-C class
  • Add non-virtual methods to a C++ class
  • Add public structures
  • Add public functions
  • Fix bugs that do not change your public interfaces
  • Make enhancements that do not change your public interfaces

Any time you change the public interfaces of your framework, you must update its compatibility version number. If your changes are restricted to bug fixes or enhancements that do not affect the framework’s public interfaces, you do not need to update the compatibility version number.