一、库的概念
库(Library)
- 就是一段编译好的
二进制代码
,加上头文件就可以供别人使用。
什么时候会用到库?
- 1- 模块代码需要给别人使用,但不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件;
- 2- 模块不会进行大的改动的代码,想
减少
编译的时间,可以把它打包成库;因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,节约浪费编译时间;
Link 的方式有两种:
静态
动态
库文件
- 动态库
. tbd
.framework
.dylib //已被. tbd取代
- 静态库
.a //纯二进制文件
.framework //二进制文件 + 资源文件
.a和.framework的区别
- .a是纯二进制文件,.framework中有二进制文件和资源文件;
- .a文件不能直接使用,至少要有.h文件配合;.framework文件可以直接使用;
-
.a
+.h
+sourceFile
=.framework
; - 建议用.framework;
静态库 static
- 也叫静态链接库;
- 在编译的时候会被直接
拷贝
一份到目标程序里,在目标程序里,这段代码不会再改变
; - 好处:编译完成之后,库文件实际上就没有作用了。目标程序没有外部依赖,直接就可以运行。
- 缺点:会使用目标程序的
体积增大
。
动态库 dynamic
- 也叫动态链接库;
- 在编译时
不会
被拷贝到目标程序中,目标程序中会存储指向动态库的引用
。等到程序运行时
,动态库才会被真正加载进来,所以可以随时对库进行替换,且不需要重新编译代码; - 同一份库可以被多个程序使用,也称
共享库
; - 优点:不需要拷贝到目标程序中,
不会
影响目标程序的体积; - 缺点:动态载入会带来一部分
性能损失
,使用动态库也会使得程序依赖于外部环境;如果环境缺少
动态库或者库的版本不正确,就会导致程序无法运行;
二、 framework概念
- 是一种
打包方式
; - 将库的
二进制文件
、头文件
、有关的资源文件
打包到一起,方便管理和分发;
framework种类:
- Dynamic Framework
系统动态库
- static framework
静态库
- embedded framework
伪动态库
1- Dynamic Framework
- 动态库:具有动态库的特征;
-
系统提供
,如:UIKit.framework -
不需要
拷贝到目标App中; - 注意:用户不可以制作;
2- Static Framework
- 静态库,具有静态库的特征;
- 用户可以制作,为:
二进制代码
+头文件
+资源文件
;
3- Embedded Framework
-
伪动态库
,具有部分
动态特征; - 不能像系统动态库那样,在
不同App
之间共享; - 只能在
App Extension
和App
之间共享动态库 (App Extension相当于一个运用的插件); - 需要在工程
General
->Embedded Binaries
添加这个动态库,才能使用; - 最后要拷贝到目标App中;所以在每个App的
IPA的framework
目录下,都会有一份; - 注意:开发者手动创建的,就是这种伪动态库,和系统的动态库是有区别的;
三、创建framework
1)创建Framework模板
1- 创建Static Framework
1.2)创建好后,展示的目录
1.3)修改库类型
- 在
Build Settings->Linking->Mach-O Type
修改为Static Library
1.4)创建同名类
- 在类中编写一个测试方法
//StaticFramework.h
#import <Foundation/Foundation.h>
@interface StaticFramework: NSObject
- (void)log; //暴露给外部使用
@end
//StaticFramework.m
#import "StaticFramework.h"
@implementation StaticFramework
- (void)log {
NSLog(@"Hello Static Framework!");
}
@end
1.5)用tree工具查看目录
- 在
StaticFramework.framework
目录下,执行tree
命令;
.
└── StaticFramework.framework
├── Headers
│ └── StaticFramework.h
├── Info.plist
├── Modules
│ └── module.modulemap
├── StaticFramework
└── _CodeSignature
├── CodeDirectory
├── CodeRequirements
├── CodeRequirements-1
├── CodeResources
└── CodeSignature
4 directories, 9 files
2- 创建Embedded Framework
2.2)创建好后,展示的目录
2.3)修改库类型
- 在
Build Settings->Linking->Mach-O Type
修改为Dynamic Library
2.4)创建同名类
- 在类中编写一个测试方法
//EmbeddedFramework.h
#import <Foundation/Foundation.h>
@interface EmbeddedFramework: NSObject
- (void)log; //暴露给外部使用
@end
//EmbeddedFramework.m
#import "EmbeddedFramework.h"
@implementation EmbeddedFramework
- (void)log {
NSLog(@"Hello Embedded Framework!");
}
@end
2.5)用tree工具查看目录
- 在
EmbeddedFramework.framework
目录下,执行tree
命令;
.
└── EmbeddedFramework.framework
├── EmbeddedFramework
├── Headers
│ └── EmbeddedFramework.h
├── Info.plist
├── Modules
│ └── module.modulemap
└── _CodeSignature
└── CodeResources
4 directories, 5 files
附上tree工具:树形目录图tree
四、使用Framework
- 将Static Framework、Embedded Framework添加到demo项目中;
- 分别导入Static Framework、Embedded Framework
头文件
; - Static Framework可以直接使用;
- Embedded Framework需要修改
General -> Frameworks,Libraries,and Embedded content -> Embed
,改为Embed&Sign
;
//导入头文件
#import "ViewController.h"
#import <StaticFramework/StaticFramework.h>
#import <EmbeddedFramework/EmbeddedFramework.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[StaticFramework new] log];
[[EmbeddedFramework new] log];
}
@end
//项目打印
2021-02-25 18:02:46.795063+0800 FrameworkDemo[58597:1603602] Hello Static Framework!
2021-02-25 18:02:46.795842+0800 FrameworkDemo[58597:1603602] Hello Embedded Framework!
- 注意:如果动态库
没有修改Embed
,会出现以下错误:
Reason: image not found
五、Embed&Sign
- 如何知道要
Frameworks,Libraries,and Embedded content
是选什么?
Do Not Embed
Embed&Sign
Embed Without Signing
1- Embed
- 嵌入,用于
动态库
; - 动态库在运行时链接,所以他们需要打进bundle中;
//进入库目录下,终端执行
file EmbeddedFramework.framework/EmbeddedFramework
打印结果:
//静态库
StaticFramework: current ar archive random library
//动态库
EmbeddedFramework: Mach-O 64-bit dynamically linked shared library x86_64
-
current ar archive
:静态库,选择:Do not embed
; -
Mach-O 64-bit dynamically linked
:动态库,选择Embed
;
2- Sign
- 用于动态库;
//进入库目录下,终端执行
codesign -dv EmbeddedFramework.framework
-
code object is not signed at all
或adhoc
:选择Embed and sign
- 其它:已经正确签名:选择
Embed Without Signing