这篇文章主要是对 WWDC 22 的视频 Link Fast——Improve build and launch times 进行归纳总结。

视频里聊到了,静态库和动态库的一些链接细节,以及 Xcode 14 为咱们供给了哪些东西,来对咱们的编译时长,做一些或许性的优化。

苹果在 Xcode 14 发布了他们开发的最新的静态库链接器——ld64,苹果聊到了4种新的链接器配置,用来为开发者的编译加快——但苹果也说,具体有没有用,还得你亲自在工程里试了,才知道。:)这很苹果。

静态库的选择性链接——经过-all_load和-dead_strip规避

默认的情况下,链接器是按函数的调用次序进行链接的,这意味着,整个链接是单线程的——由于只要在a调用了b的情况下,链接器才会去链接b。

但假如不需要链接器去进行这个判断,就能够让整个链接进程并发。

能够经过在 other linker flags 中增加-all_load参数,来告知链接器,全量链接静态库的符号,不需要选择性链接,然后加快链接的进程。

-all_load 也有缺点,由于或许会把不在运用的代码也加载进来,导致包体积变大。

但也能够经过增加 -dead_strip 链接器选项,来将无法访问的代码和数据移除。

何时运用 静态库?

  • 任何代码改变,都会导致静态库重编,所以用于封装成静态库的代码,最好是比较稳定的代码。
  • 选择性加载是连接器的前史行为,并且会拖慢链接进程,且导致链接只能次序发生,而不能并行发生——假如工程里的确不需要,能够增加-all_load 链接标记,苹果最新的静态库链接器 ld64 能借此加快链接进程。

-no_exported_symbols 选项

WWDC 22——Link Fast — 加速编译和App启动

一般来说主程序不需要导出,这一步意味着编译器在编译时会生成并导出一个前缀树型结构的符号文件,后续或许被用到——假如工程有插件、或关联了XCTest的话,最好不敞开该选项。

但这个导出数据,假如量不大的话,其实对于链接的时刻的影响,十分有限。

但也能够用图中的命令看看,假如导出数量很大,但该成果没用上,的确能够考虑不导出。

dyld_info -exports /path/to/binary | wc -l

-no_deduplicated

取消去重,能够在debug模式中运用,看看是不是能加快编译。


动态库方面

运用动态库能够加快编译,但发动速度会变慢。

动态库的链接原理是,编译进程中,不需要将主项目中对动态库中的接口的调用,链接到主项目中,而是在主项目中,留下了类似协议的调用。直到发动APP,才将真正的完成,关联起来——也便是 dyld 进程。

官方对动态库的态度:

为了发动更快——少点用动态库:)。

但静态库太多的话,的确会拖慢编译速度,而动态库有助于这一点。

重点是找到一个平衡点——静态库用多少,动态库用多少。

最低运行版别调到 13.4 以上,App 的发动在 iOS 16 会得到加快

由于苹果在 iOS 13.4 以上的设备布置了动态库链式修复(dylib Chain Fixups)的功能,假如将布置最低版别设到 13.4 以上,发动时的动态库加载进程会得到加快。

一些用来检查发动时 dyld 进程细节的命令行东西

  • dyld_usage

WWDC 22——Link Fast — 加速编译和App启动

  • dyld_info

检查Dyld 信息


总结

  • 回忆 app 中对静态库,动态库的运用情况,并考虑它们对编译时长,以及发动的影响;
  • 测验运用 Xcode 14 编译项目;
  • 测验前面说到的4个编译选项,看看对编译时长,是否有真实的优化效果——从视频里的意思,运用在静态库,或者主工程上较为适宜(笔者在一个大小适中的项目上进行了测验,成果表现到的优化比较有限——:)这又很苹果——也或许每个项目情况都不同,还请读者自行测验哈~);
  • 将 iOS 最低布置版别设置到 13.4 或更高,然后在 iOS 16 上看看 App 的首次发动时长,是不是有所优化。