iOS的动态库和静态库的差异区别以及静态库的好处

iOS的动态库和静态库的差异区别

好的,这是一个非常核心的iOS开发知识点。我们来详细、清晰地解析一下iOS中动态库和静态库的差异区别。

核心概念

* **库**:本质上是一个可执行代码的二进制集合,可以被其他程序调用。它封装了功能、资源,供开发者复用,避免重复造轮子。

* **静态库**:在**编译链接期**,被完整地复制到最终的可执行文件(.app)中。

* **动态库**:在**程序运行时**,由系统动态地加载到内存中。多个应用程序可以共享同一份动态库的实例。


详细对比表格

| 特性 | 静态库 | 动态库 |

| :--- | :--- | :--- |

| **文件格式** | `.a` 或 `.framework` (包含Headers的文件夹) | `.dylib` 或 `.framework` (包含Headers的文件夹) |

| **整合时机** | **编译时** | **运行时** |

| **整合方式** | 被完整地复制到最终的可执行文件中 | 不会被复制到可执行文件,只记录引用路径 |

| **App包体积** | **较大**(因为库的代码被内嵌) | **较小**(主程序体积小,但需要携带动态库) |

| **内存占用** | 可能**较高**(如果多个App使用同一静态库,各自内存中有一份副本) | **较低**(系统内存中只保留一份副本,供多个App共享) |

| **加载速度** | **启动稍快**(因为代码已在主程序二进制内,无需查找加载) | **首次加载稍慢**(需要查找和加载动态库) |

| **共享性** | **不可共享**(每个App都包含自己的副本) | **可以共享**(系统级动态库,如UIKit) |

| **热更新** | **不支持**(库代码已编译进App,上架后无法修改) | **原则上不支持**(AppStore审核禁止,但技术上可行) |

| **依赖管理** | 简单,所有代码都已包含,不存在依赖问题 | 需要确保目标设备上有正确的库版本,否则会崩溃 |

| **Apple的立场** | 对第三方开发者**推荐使用** | 对第三方开发者**限制使用**(只能使用系统提供的) |


深入解析与iOS特性

1. 静态库

* **工作原理**:

  1. 你在编译你的App时,链接器(Linker)会找到你引用的静态库(.a或.framework)。

  2. 它将你的目标文件(.o)和静态库中**被用到的代码**一起打包,生成一个单一的、庞大的可执行文件。

  3. 最终你的`.app`文件中,这个可执行文件已经包含了所有静态库的代码。

* **优点**:

* **部署简单**:App是一个自包含的整体,不存在运行时找不到库的依赖问题。

* **性能**:启动时略快,因为减少了动态链接的过程。

* **隐私和安全**:代码被内嵌,更难被单独逆向。

* **缺点**:

* **App体积增大**:如果多个App使用同一个静态库,那么每个App内部都有一份相同的代码,占用用户磁盘空间。

* **更新困难**:如果库需要修复Bug或更新功能,你必须重新编译整个App并发布新版本给用户更新。

2. 动态库

* **工作原理**:

  1. 编译时,链接器只记录下你使用了哪个动态库(比如 `libSystem.dylib`),以及所需的符号(函数、变量名)。

  2. 生成的App可执行文件**并不包含**动态库的代码。

  3. 当App启动时,系统的动态链接器(`dyld`)会根据记录的信息,去指定的路径(如系统目录 `/usr/lib`)查找并加载所需的动态库到内存中。

  4. 如果多个App使用同一个系统动态库,它们会共享内存中已加载的那一份。

* **iOS对动态库的限制(非常重要!)**:

* **App Store审查规定**:第三方开发者**不允许**在自己的App中嵌入并使用自定义的动态库(`.dylib` 或自定义的 `.framework`)。这是因为动态库的加载机制可能被用来执行热更新或下载代码,这违反了App Store的安全和隐私准则。

* **唯一例外:App Extensions**

当你开发一个 **App Extension**(如Today Widget、Share Extension等)时,你的主App和Extension之间**可以且推荐**通过创建一个**自定义的动态 `.framework`** 来共享代码。这是因为主App和Extension属于同一个App Group,它们运行在同一个沙盒容器内,共享动态库是安全的,并且能有效减少整体安装体积。

* **系统动态库**:

* iOS系统中的所有基础框架,如 `UIKit`, `Foundation`, `CoreGraphics` 等,都是以动态库的形式提供的。这就是为什么你的App体积不会因为使用了庞大的UIKit而变得巨大的原因。


如何区分 `.framework` 是静态还是动态?

`.framework` 只是一个文件夹结构(Bundle),它既可以包裹静态库,也可以包裹动态库。

* **查看文件类型**:

在终端中,进入 `.framework` 文件夹,使用 `file` 命令查看同名文件(真正的二进制文件)。

```bash

查看一个 .framework 是静态还是动态

cd MyFramework.framework

file MyFramework

```

* **静态库输出**:`current ar archive random library`

* 这表示它是一个归档文件(`ar`命令打包的 `.o` 文件集合)。

* **动态库输出**:`Mach-O dynamically linked shared library`

* 这明确指出了它是一个动态链接的共享库。

* **在Xcode中查看**:

在Target的 **"General" -> "Frameworks, Libraries, and Embedded Content"** 部分,系统提供的动态库会标记为 **"Do Not Embed"**,而你自己创建的动态库需要标记为 **"Embed & Sign"**。静态库则通常不需要嵌入这一步。


总结与选择建议

* **对于第三方iOS开发者**:

* **制作给别人用的库**:你**只能**提供**静态库**(`.a` 或静态的 `.framework`)。

* **在自己的多个App间共享代码**:使用**静态库**,或者通过源码依赖(如CocoaPods、Swift Package Manager)。

* **在主App和App Extension间共享代码**:这是唯一推荐使用**自定义动态库**(动态的 `.framework`)的场景。

* **对于Apple**:

* 它提供所有的系统框架作为**动态库**,以实现最佳的资源利用和共享。

简单来说,在iOS生态中,由于沙盒和安全限制,**"静态库是常态,动态库是特例"**。这个特例仅限于系统框架和App与其Extension之间的代码共享。

广告SDK用静态库的好处



相关推荐
ManageEngine卓豪3 小时前
企业 Mac终端如何统一管控?配置、补丁与应用的落地框架
macos·mdm·uem·终端管理系统
黑化旺仔7 小时前
【OC】Runtime:类元数据、加载初始化与消息派发
开发语言·macos·ios·objective-c
songgeb8 小时前
iOS App支持设置RTL语言的实践
ios·swift·ui kit
软泡芙8 小时前
【iOS】swift启动屏显示黑屏
ios
用户693717500138410 小时前
当你向领导申请 AI 编程工具预算时,如果领导追问“能提效多少,有量化数据吗”,你该怎么回答?
android·后端·ios
Layer10 小时前
一些脱离 Mac 依赖的 Agent 操作 iPhone 实现
ios·ai编程·测试
用户693717500138412 小时前
当我说 Claude 搭配 GLM-5.3-Flash 太好用了,同事却提醒我:你可能正在失去对代码的掌控
android·后端·ios
茶底世界之下12 小时前
一键裁方会丢掉什么?用 Awaking 给园林照片做两种画幅
ios
Marco_Marco13514 小时前
定位SDK接入实战:Android/iOS/鸿蒙三端怎么选、怎么接
android·ios·harmonyos
老李IT笔记1 天前
关掉设备上的 AI 扩展:两个键各管一层,配错了等于没配
人工智能·ios·智能手机