.a 和 .framework 静态库的制作步骤

什么是库?
库就是把一对.h .m 图片资源 bundle 文件打包起来的一个文件。

库的分类
开源库:源代码是公开的,主要体现在可以看到.m 文件的内部实现。例如在 github 上大多数库下载下来之后,都可以看到 .h 和 .m 文件。
闭源库:不公开源代码,一般只暴露 .h 文件。一般都是编译过的二进制代码,看不到具体实现。
闭源库又分:静态库 & 动态库

静态库的存在形式:
.a
.framework

动态库的存在形式
.dylib
.framework

静态库和动态库的区别?
1. .a 一定是是静态库,dylib(dynamic library)一定是动态库。.framework 可能是静态库,也有可能是动态库。
2. 静态库在链接时,会被完全赋值到可执行文件中。如果多个 App 都使用了同一个静态库,那么每个 App 都会拷贝一份静态库,缺点是浪费内存。类似定义一个变量,使用该基本变量的时候,都是复制了一份便变量的值。
3. 动态库不会复制,只有一份,程序运行时动态加载到内存中,系统最多只加载一次,多个程序公用一份,节约了内存。类似于使用对象的引用。但是如果在 iOS 项目中使用了自定义动态库,苹果是不允许上架的。在 iOS 8 之后,苹果开放了动态加载 .dylib 的接口,用于挂载 .dylib 动态库。

使用静态库时,会被完全复制到可执行文件中,多次使用就多次复制。


.a 和 .framework 静态库的制作步骤_第1张图片
静态库的内存使用

动态库链接时不复制,程序运行时由系统动态加载到内存,供程序使用。
而且系统只会加载一次,多个程序公用,节省内存。


.a 和 .framework 静态库的制作步骤_第2张图片
动态库的内存使用

静态库的运用场景?
1. 保护公司的核心代码,如讯飞语音搜索摸索了好多年得到的成果当然要保存起来,都公开了,公司如何生存?
2. 将 MRC 的项目打包成静态库,可以在 ARC 模式下直接使用。免去了配置 .m 文件的 -fno-objc-arc 的配置。

静态库的运用场景?
.a + .h
.h 可以看到头文件,也就是方法的声明
.a & .framework 可以看作是所有的 .m 代码加密后的一个二进制文件。

.bundle
在使用第三方库的时候,有时候会带上 .bundle 文件。.bundle 实际上是一个物理文件夹,里面可以放图片等资源。
因为 .bundle 是一个物理路径文件夹,所以,里面放的资源文件不会和当前的 target 项目的资源文件重名。

.a 和 .framework
既然 .a 和 .framework 都可以完成静态库的封装。
它们之后有和区别呢?
使用 .a 打包静态库时,包含了 .a 静态库 + .h 头文件 + bundle 资源文件
使用 .framework 打包静态库时,所有的文件都包含在 .framework 包里了,比 .a 方便不少。


所有的库不管是.a .dylib .framework 最终目的,都是为了打包一堆 .h ,.m ,bundle 资源文件。并对外隐藏 .m 的实现细节。

.a 静态库的制作步骤

第一步,创建一个 静态库项目

创建好的资源管理器


.a 和 .framework 静态库的制作步骤_第3张图片
创建好的.a静态库

第二步,添加自己的 .h , .m 文件,并实现。

由于系统会默认帮助我们添加一对 .h .m ,所以我就不添加了。直接用这对。

第三步,在 .h , .m 中定义方法的声明 和 实现。

+ (void)classMethod;

- (void)instanceMethod;

+ (void)classMethod {
    NSLog(@"我是来自 RelaxALib.a 静态库的类方法");
}

- (void)instanceMethod {
    NSLog(@"我是来自 RelaxALib.a 静态库的实例方法");
}

第四步骤,设置编译参数。

.a 和 .framework 静态库的制作步骤_第4张图片
设置编译参数

第五步,选择模拟器 AND 真机设备,分别 command + b 一次。完成 .a 库的编译。

.a 和 .framework 静态库的制作步骤_第5张图片
image.png
.a 和 .framework 静态库的制作步骤_第6张图片
image.png

第六步,右键 RelaxALib.a -> show in finder
可以看到,有两个文件夹。

.a 和 .framework 静态库的制作步骤_第7张图片
image.png

两个文件夹里,都有 libRelaxALib.a 这个文件。这个就是把 .m 文件实现编译成的二进制库。

还有一个比较重要的文件夹 include ,这里面放的是这个库里的头文件。

第七步 使用 lipo -create 模拟器 lib.a路径 真机 lib.a路径 -ouput 存储新的路径/newLib.a命令。

为什么要用这个命令?
因为在编译生成库的时候,我们的选择只能是单一的模拟器或者真机。
在模拟器下编译的包只能跑在模拟下。
在真机下编译的包只能跑在真机下。

使用 lipo -info lib.a路径 查看包支持的架构。

.a 和 .framework 静态库的制作步骤_第8张图片
image.png

得到的结果是 : i386x86_64 ,分别是 32 位和 64 位操作系统的架构。

.a 和 .framework 静态库的制作步骤_第9张图片
image.png

而在真机下 command + b 编译的包支持的架构则是 armv7 & armv7s & arm64
armv7 是 iPhone 4s 的 CPU 架构。
armv7s 是 iPhone5 & iPhone 5c 的 CPU 架构。
arm64 则是 iPhone5s 以及以上的 CPU 架构了。

所以,可以通过 lipo -info xxx.a 的命令来查看库支持的架构。

第八步,将两种架构的包合并在一起,变成真机和模拟器都可以使用的包。
使用 lipo -create 真机.a路径 模拟器.a 路径 -output 组合包.a 路径

.a 和 .framework 静态库的制作步骤_第10张图片
image.png

合并两种框架后的新包,放在桌面了。

.a 和 .framework 静态库的制作步骤_第11张图片
image.png

可以使用 lipo -info 命令来查看此包支持的 CPU 架构。

lipo -info newLib.a
.a 和 .framework 静态库的制作步骤_第12张图片
image.png

第九步,使用我们刚编译 + 合并 完成可以跑在真机 & 模拟器上的 .a 包。
创建一个新的项目

image.png

然后使用包里定义好的功能即可。

15223247637135.gif

.framework 静态库制作

.a 是静态库 .dylib 是动态库。
.framework 是动态库也可以是静态库。

为什么有 .a 静态库了,还要出一个 .framework 静态库呢?

个人感觉,在使用层面上。 .a 静态库的使用,必须是 .h(include 文件夹) + .a 文件 + bundle 三个东西。
如果使用 .framework 静态库的话,使用起来很方便。

这里主要说明 .framework 静态库的制作步骤。

第一步,创建一个 .framework项目

.a 和 .framework 静态库的制作步骤_第13张图片
创建.framework 项目

创建好之后的文件夹结构

.a 和 .framework 静态库的制作步骤_第14张图片
image.png

第二步:framework 的一些基本参数配置

.a 和 .framework 静态库的制作步骤_第15张图片
image.png

第三步,创建自己的包文件。

.a 和 .framework 静态库的制作步骤_第16张图片
image.png

第四步:配置哪些头文件可以被使用包的项目导入

.a 和 .framework 静态库的制作步骤_第17张图片
15223726953041.gif

在 framework 本身里面,如果没有把 .h 头文件添加到 pulbic 节点,而在 '库名.h' 文件中导入这个头文件。
在库本身编译的过程中,不会有任何问题。
但是在把库给其他项目使用的时候,会报头文件找不到的错误?
那这个 private 的节点有什么作用吗?隐藏了头文件,对库自己也隐藏了?

第五步,在框架自己生成的 MyFirstFrame.h 文件里导入头文件

.a 和 .framework 静态库的制作步骤_第18张图片
image.png
#import 
#import 

格式 :#import <框架名/文件.h>

第六步,分别选择模拟器和设备,进行 command + b 编译

.a 和 .framework 静态库的制作步骤_第19张图片
image.png

第七步:将模拟器包和真机包合并

.a 和 .framework 静态库的制作步骤_第20张图片
image.png

补充,合并的不是MyFirstFramework.framework
MyFirstFramework.framework 可以理解成一个文件夹。
合并的是此文件夹里的 MyFramework

.a 和 .framework 静态库的制作步骤_第21张图片
image.png

第八步,把合并好的 MyFirstFramework替换到任意一个包里的 MyFirstFramework
什么意思?
我们可以看一下 MyFirstFramework.framework 这个文件里面的内容。

.a 和 .framework 静态库的制作步骤_第22张图片
image.png

文件夹里,本来就有 headers,info.plist,modules,MyFirstFramework。这4个元素。
它们在一起组成了一个完成的 MyFirstframework.framework 的包。

我们现在用命令生成了一个新的 MyFirstFramework文件。其他的文件对于一个完成的 MyFirstFramework.framework包来说,是比不可少的,也是固定不变的
我们要做的,就是把自己合并完毕后的 MyFirstFramework 替换一下就行了。
所以,随便找一个之前的不管是真机还是模拟器的MyFristFramework.framework包文件夹,替换里面的 MyFristFramework包即可。

第九步,使用我们刚创建的 .framework 包

image.png

一些坑特别注意

对于 .framework 包封装用命令的时候。
MyFristFramework.framework 是文件夹,只是的库代码二进制文件是文件夹内的 MyFristFramework二进制文件。
lipo -create & lipo -info 针对的是 MyFristFramework 文件 ,而不是 MyFristFramework.framework 文件夹

你可能感兴趣的:(.a 和 .framework 静态库的制作步骤)