不要被 ChatGPT 误导了,正确认识 iOS 中静态库和动态库

凌晨两点半
凌晨两点半
发布时间:2026-08-24| 9人浏览过
原创

前言

不少 iOS 开发者第一次比较静态库和动态库时,都会被一些“动态库更小、更方便、还能被多个应用共享”的说法带偏。问题在于,这些结论放到 iOS 的实际发布和运行环境里,往往只成立一部分。下面就按最容易误解的几个问题逐条拆开,顺着文件形态、复用范围、包体积和启动过程来判断,最后落到项目里到底该怎么选。

不少 iOS 开发者第一次比较静态库和动态库时,都会被一些“放之四海而皆准”的结论带偏,比如动态库一定更小、更新更方便、还能被多个应用共享。问题在于,这些说法放到 iOS 的实际发布和运行环境里,往往只对了一半。

这篇文章不打算重复教科书式定义,而是按开发中最容易踩坑的几个问题来梳理:文件形式到底怎么区分、动态库能不能跨 App 共享、包体积和启动速度该怎么看,以及项目里到底该怎么选。看完之后,你可以用更接近 iOS 实际约束的标准来判断静态库和动态库。

.framework 不等于动态库

很多文章一上来会把静态库等同于 .a,把动态库等同于 .dylib 或 .framework。这种说法不完整,甚至会直接误导选型。

说明 .a、.framework、.dylib 三者关系,以及 framework 不等于动态库的结构化信息图
别把 .framework 直接等同于动态库先把文件形式和链接属性分开看,能避免一上来就把 .framework 误判成动态库。

静态库不只有 .a 一种形式

在 iOS 开发里,.a 确实是典型的静态库文件,但它不是静态库的唯一表现形式。.framework 也可能是静态库,只不过它采用的是框架封装形式。

.framework 既可以是静态的,也可以是动态的

真正需要区分的不是文件后缀本身,而是这个 framework 内部链接方式是什么。也就是说:

  • .a 是静态库的一种常见形式;
  • .framework 既可能是静态库,也可能是动态库;
  • .dylib 则通常用于动态库语境。

所以,单看项目里出现了 .framework,并不能直接得出“这是动态库”的结论。

动态库真的能被多个 App 共享吗

这是另一个特别常见的误区。很多解释会说,动态库位于应用之外,因此多个应用程序可以共享同一份动态库文件。放在通用操作系统语境里,这句话不算完全错,但放到 iOS 上就不准确了。

说明 iOS 中动态库复用边界的关系图,区分系统动态库共享与自定义动态库仅主包和扩展复用
动态库的“共享”在 iOS 里有边界动态库的优势不能脱离 iOS 运行环境来谈,系统库共享和业务库复用是两回事。

只有系统动态库能被多个应用共享

在 iOS 开发中,真正能被多个应用共享的,主要是系统提供的动态库。它们由系统统一提供、统一装载,因此不同 App 可以依赖同一份系统库。

自定义动态库通常只在主包和扩展之间复用

对于开发者自己打包的动态库,情况并不是“多个 App 共用一份”。在 iOS 的发布模型下,用户自定义动态库不能像桌面系统那样被不同应用随意共享。更现实的复用场景是:

  • 同一个 App 的主包使用该动态库;
  • 同一个 App 的 Extension 也使用该动态库;
  • 主包和扩展之间共享同一份库代码。

因此,讨论动态库优势时,应该把“跨多个独立 App 共享”改成“在主包和扩展之间复用”才更符合 iOS 实际。

包大小并不是动态库天然占优

“静态库会让包变大,动态库会让包变小”是最容易被直接转发的一条结论,但它并不适合作为通用规则。

说明静态库与动态库在包大小和启动速度上的取舍关系信息图
包体积与启动速度该怎么判断体积和启动性能都不能只看“静态”或“动态”标签,关键在于死代码剥离和是否存在复用。

静态库有机会借助死代码剥离减小体积

静态库在链接进可执行文件后,包体积不一定会变大,甚至有可能更小。一个关键原因是链接器支持可执行文件的死代码剥离(Dead Code Stripping)。

这一功能可以在 Xcode 的 Build Settings 中开启。启用之后,链接器会根据实际使用到的符号进行分析,把没有用到的代码剥离掉,从而节省空间。

动态库节省体积的前提是复用

动态库什么时候更有体积优势?前提通常是“有复用”。例如:

  • 主二进制文件需要用到这份库;
  • 扩展也需要用到同一份库;
  • 这时把它做成动态库,可以避免重复塞进多份二进制中。

但如果没有这种复用场景,动态库通常并不会天然更省,很多情况下包大小反而会比静态库更大。

更新维护并没有本质上的高下之分

不少对比文章会把“动态库更新更方便、静态库维护更麻烦”写成固定结论,但在 iOS 应用开发里,这个说法并不牢靠。

从实际工程角度看,更新和维护难度更多取决于你的项目结构、发布流程和依赖管理方式,而不是简单由“静态”还是“动态”决定。至少在本文讨论的 iOS 场景里,把动态库直接概括成“更新库文件即可,无需重新编译应用程序”,并不适合作为面向 App 开发者的通用判断。

更稳妥的说法是:在更新和维护上,两者没有特别明显的天然优劣。

启动速度为什么通常是静态库更占优

相比前面几个点,启动速度往往是更值得认真看的实际指标。

iOS 会在启动阶段处理动态库加载

从技术上说,应用启动后再通过 dlopen() 加载 dylib 并非做不到。但在 iOS App 场景下,苹果不允许把这类做法作为绕过审核或规避正常链接流程的手段,否则无法上架 App Store。

在默认情况下,iOS 应用会在启动时由动态链接器加载所有动态库。

静态库少了一次启动期链接环节

这意味着,相比动态库,静态库在启动阶段少了动态链接这一环节。也正因为如此,理论上静态库在启动速度上通常会更快一些。

这里要注意的是,这个结论讨论的是“通常情况下”的趋势,不代表所有项目只要改成静态库,启动时间就一定立刻大幅改善。但从原理上看,静态库在启动路径上确实更短。

项目里到底该怎么选

如果只是想得到一个实际可执行的选择建议,可以先按下面这套判断来做。

大多数情况下,优先从静态框架开始

如果你还不确定自己的框架究竟该做成静态库还是动态库,一个务实的起点是优先选择静态框架。

这样做的原因主要有两点:

  • 启动速度上通常更有优势;
  • 启用 Dead Code Stripping 后,有机会剔除未使用代码,控制包体积。

需要主包和扩展复用时,再考虑动态库

如果你的库需要在主包和 Extension 之间复用,那么动态库就值得认真考虑。因为这时它的复用价值更容易体现出来,包大小上的取舍也更可能成立。

结论

关于静态库和动态库,更接近 iOS 实际情况的结论是:静态库通常在启动速度上更有优势;动态库只有在确实存在复用场景时,才更容易体现价值;至于更新和维护,两者并没有想象中那么大的差别。

简化成一句话就是:先别被“动态库天然更高级”这种印象带跑,大多数普通场景可以先从静态框架开始;只有当你的库需要被主包和扩展共同复用时,再认真评估动态库是否更合适。

本文同步自微信公众号“iOS新知”。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。