之前关于这两者的概念仅仅停留在八股文的认知水平(可能八股都答的一塌糊涂)亦或许便是道听途说,知道下怎样用就完事儿了,看了很多相关的资料,看了就忘,干脆自己整理一下,理顺一下自己的思路,体系化的了解一下,防止自己变成脑残。。。
在此之前,咱们对一些常识性的东西复习一下
.a .framework
.a 是单纯的二进制文件,.framework是二进制文件+资源文件。
程序履行的流程
预处理—>编译—>汇编—>链接(汇编程序生成的目标文件并不能被立即履行,还需求经过链接器(Linker),将有关的目标文件彼此相连接,使得所有的目标文件成为一个能够被操作体系载入履行的一致整体。)
- 静态链接:直接在编译阶段就把静态库加入到可履行文件当中去。长处:不必忧虑目标用户缺少库文件。缺点:终究的可履行文件会较大;且多个使用程序之间无法同享库文件,会形成内存糟蹋。
- 动态链接:在链接阶段只加入一些描述信息,等到程序履行时再从体系中把相应的动态库加载到内存中去。长处:可履行文件小;多个使用程序之间能够同享库文件。缺点:需求保证目标用户有相应的库文件。
关于iOS使用的发动流程
1. 解析Info.plist
2. Mach-O(可履行文件)加载
dylib loading time
rebase/binding time
3. 程序履行
….这儿其实还是想简述一下加载流程,由于我在这儿一直也有个误区,使用在发动前静态库现已存在于可履行的二进制文件当中了,而动态库在发动后才进行加载等一系列操作。
为什么要阐述这些老生常谈的东西呢,由于我曾经一直对动态库的加载和编译时机存在误解,咱们拿一个具体的工程举例
咱们从产物的包内容找到一路找到可履行文件,能够看到可履行文件和framework是独自存在的 静态库在编译的时分就被打到二进制文件当中了
怎样差异动态库还是静态库
一般来说,动态库以.dylib
或许.framework
后缀结束;静态库以.a
和.framework
结束。
这儿列出几种办法差异动态库还是静态库
- 检查Mach-O Type来差异
- 检查ipa的目录结构
- 经过file工具检查
动态库/静态库的加载进程 & 两者之间的差异
一般来说,build一个项目的进程是先compile然后再link,然后才有一个可履行文件。link的时分要做的一件工作便是把各种函数符号转换成函数调用地址,然后终究生成的可履行文件就能够直接调用到函数了。
1.静态库在build的时分就把库里面的代码链接进可履行文件。这儿还要再弥补一句,会将静态库中被运用的部分都添加到使用程序的可履行文件,这意味着使用程序的可履行文件大小会跟着静态库数量的增加而增大。在运转时,静态库会跟着使用程序的可履行文件一同加载到同一代码区。在 iOS 开发中,使用程序的可履行文件便是 ipa 解压后,包内容中与 app 同名的可履行文件
。
2.动态库的做法不一样,不会在build的时分就把代码link进可履行文件,这儿咱们只对动态链接库进行阐述 关于动态链接库而言,build可履行文件的时分需求指定它依靠哪些库,当可履行文件运转时,假如操作体系没有加载过这些库,那就会把这些库跟着可履行文件的加载而加载进内存中,供可履行程序运转。假如多个可履行文件依靠同一个动态链接库,那么内存中只会有一份动态链接库的代码,然后把它同享给所有相关可履行文件(APP)的进程运用,所以它也叫同享库
那简言之:动态链接库在可履行文件得到运转的时分就加载 这句话很有养分
在ios程序的发动流程中,咱们会先加载使用的可履行文件(这就包括了静态库文件)然后才是动态库的一系列加载流程(程序履行 静态库:链接时完好地仿制至可履行文件中,被屡次运用就有多份冗余仿制,存在方式:.a和.framework 动态库:链接时不仿制,程序运转时由体系动态加载到内存,供程序调用,体系只加载一次,多个程序共用,节约内存。存在方式:.dylib和.framework
之前对这儿一直存在误区,这儿的加载是以可履行文件(APP)为单位的。还有便是咱们这儿谈的动态库都都是体系层面的动态库,差异也是针关于静态库和体系动态库而言的。别的便是静态库在一开始就存在于可履行文件中,而动态库在运转时动态的进行绑定。
use_frameworks!
podfile中经常会加上这句话,咱们来看一下实践的作用和效果 当运用 use_frameworks的时分 cocoapods会生成对应的 frameworks 文件(动态库) 在Link Binary With Libraries:会生成Pods_工程名.framework,包含了其它用cocoapods导入的第三方框架的.framework文件
当不运用use_frameworks!(静态库)cocoapods会生成相应的 .a文件(静态链接库) Link Binary With Libraries: libPods-工程名.a 包含了其他用cocoapods导入有第三库的 .a 文件
当然我还注意到一些其他文件的diff 比较令我猎奇的便是这个modulemap 之前也没了解过,以后有时机研究一下
Xcode Embed
关于这个设置,之前也是不太清楚,
- 关于体系动态库,能够将
Embed
特点设置成Do Not Embed
,由于 iOS 体系提供了相关的库,咱们无需将它们再嵌入到使用程序的 ipa 包中,如:Foundation.framework
、UIKit.framework
。 - 关于用户动态库,需求将
Embed
特点设置成Embed
,由于链接发生在运转时,链接器需求从使用程序的 ipa 包中加载完好的动态库。 - 关于静态库,需求将
Embed
特点设置成Do Not Embed
,由于链接发生在编译时,编译完成后相关代码都现已包含在了使用程序的可履行文件中了,无需在使用程序的 bundle 中再保存一份。
动态库和静态库的运用场景
静态库
- 静态库主要使用于模块化,分工合作
- 避免少量改动经常导致大量的重复编译连接
- 也能够重用,注意不是同享运用
动态库
1.运用动态库,能够将终究可履行文件体积缩小
2.关于 iOS 开发来说, 由于咱们只能运用Embedding Frameworks
来运用动态库, 这样的动态库并不是真实的动态库, 其会在编译时悉数置入 app, 然后再 app 发动时悉数加载, 这样的话会导致体积大, 加载速度慢.
动静态库的混用
- 静态库能够依靠静态库
- 动态库能够依靠动态库
- 动态库不能依靠静态库! 动态库不能依靠静态库是由于静态库不需求在运转时再次加载, 假如多个动态库依靠同一个静态库, 会呈现多个静态库的仿制, 而这些仿制自身仅仅关于内存空间的消耗
但其实两者之间都是能够经过各种操作进行依靠的 静态库也是能够依靠动态库的 动态库也是能够依靠静态库的
总结
以上便是我对动态库以及静态库一些盲区的的具体总结和详细分析,总的来说,对每个人物的定位,有了更明晰的认知
弥补
用户创建伪动态库 和静态库有什么差异呢,假如有差异 具体是怎样使用的呢 有知道的朋友能够帮我解说下吗?不胜感激
参阅链接
blog.csdn.net/GeekLee609/…
/post/704110…
zhuanlan.zhihu.com/p/346683326
www.jianshu.com/p/662832e16…
chuquan.me/2021/02/14/…
zhuanlan.zhihu.com/p/346683326