iOS 动态库 & 静态库

2021-01-11  本文已影响0人  梦蕊dream

编译器

LLVM 是编译器工具链技术的一个集合。而其中的 lld 项目,就是内置链接器。 编译器会对每个文件进行编译,生成 Mach-O(可执行文件);链接器会将项目中的多个 Mach-O 文件合并成一个。

主要过程:

解释器:
在运行时才去解析代码,比在运行之前通过编译器生成一份完整的机器码再去执行的效率要低。具有动态性,程序运行后能够随时通过增加和更新 代码来改变程序的逻辑。

编译过程

链接器

Mach-O 文件里面的内容,主要就是代码和数据。它们的实例都需要由符号将其关联起来。完成变量、函数符号和其地址绑定这样的任务。

链接器在链接多个目标文件的过程中,会创建一个符号表,用于记录所有已定义的和所有未定义的符号。

主要流程:

image.png

库是共享程序代码的方式。库从本质是一种可执行代码的二进制格式,可以被载入内存中执行。出于安全性和稳定性的考虑,不想被外界知道,所以会把核心代码打包成库,只暴露出头文件以供使用。

静态库 & 动态库

静态库 & 动态库

静态库

静态库

动态库

动态库

dyld 加载动态库

启动加载时绑定和符号第一次被用到时绑定。


image.png

iOS 动态库

iOS 8 之后,iOS有了App Extesion特性;由于 iOS 主App需要和Extension共享代码,Swift语言机制也需要动态库,于是苹果后来提出了Embedded Framework,这种动态库允许APP和APP Extension共享代码,但是这份动态库的生命被限定在一个APP进程内。

App Extesion(应用扩展)

https://www.jianshu.com/p/fbab922fc175

不是一个app,而只是对于某个app内容和功能的扩展。跟随着你的app一起打包,包含应用扩展一起打包的app就叫做container app(容器app)。
运行时它并不是跟你的app在同一个进程上面,而且有可能同一个app extension会同时运行在不同的进程,因为有可能同时有几个程序都打开了这个app extension,这个用来打开某个app Extension的应用就叫做host app(宿主应用)。

  • Call Directory用来处理来电时的事项,比如黑名单机制、来电标记提醒等等
  • Photo Editing用来在相册选中相片编辑时的扩展,可以直接对相片进行一个编辑处理
  • Share用来对文件进行一个直接的分享功能,他不用唤起主App就能完成文件的分享

系统动态库和自定义动态库(Embedded Framework)区别

什么是framework

Framework是Cocoa/Cocoa Touch程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件、说明文档等集中在一起。


framework

framwork 目录

目录 bundle

framework 资源文件

工程截图 输出文件

一般如果是静态Framework的话,资源打包进Framework是读取不了的。静态Framework和.a文件都是编译进可执行文件里面的。
只有动态Framework能在.app的Framework文件夹下看到,并读取.framework里的资源文件。

let enBundle = Bundle.init(path: bundle.path(forResource: "xxxx", ofType: "xxxx") ?? "") 

静态库和动态库依赖关系

1. 静态库互相依赖

制作静态库的时候只需要有被依赖的静态库头文件在就能编译出来。

2. 动态库依赖动态库

两个动态库是相互隔离的具有隔离性。在制作的静态库的时候需要被依赖动态库参与链接,最终具体的符号决议交给dyld来做。

3. 静态库依赖动态库

静态库制作的时候也需要动态库参与链接,但是符号的决议交给dyld来做。

4. 动态库依赖静态库

静态库本质是一堆.o 的打包体,首先并不是二进制可执行文件,再者你无法保证主程序把静态库参与链接共同生成二进制可执行文件。

解决方案
目前的编译器的解决办法是,首先我无法保证主程序是否包含静态库,再者静态库也无法被dyld加载,那么我直接把你静态库的.o 偷过来,共同组成一个新的二进制。也被称做吸附性。

【如果多个动态库依赖同一静态库?】
可执文件(主程序或者动态库)在构建的链接阶段,遇到静态库,吸附进来;遇到动态库,打标记,彼此保持独立。

正因为动态库是保持独立的,可以自定义一个动态库把依赖的静态库吸附进来。对外整体呈现的是动态库特性。其他的组件依赖我们自定义的动态库,由于隔离性的存在,不会出现问题。

注意事项

静态库中有category类

【Other Linker Flags】需要添加参数【-ObjC]或者【-all_load】

【dyld: Library not loaded:XXXXXX】

打包的framework版本,需要到iOS Deployment Target设置对应版本。

Include of non-modular header inside framework module

framework类中使用了.dylib或者.tbd,首先需要在实际项目中导入.dylib或者.tbd动态库,然后需要设置【Allow Non-modular Includes ....】为YES

【Umbrella header for module 'XXXX' does not include header 'XXXXX.h'】

错把xxxxx.h拖到了public中

上一篇下一篇

猜你喜欢

热点阅读