一、库的概念
库(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;
拉入Framework
动态库Embed
//导入头文件
#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













网友评论