一、简单介绍
1.1. 什么是库
1.2. 库的分类
1.3. 静态库和动态库
二、创建静态库
2.1. 创建.a 静态库
2.2. 创建.framework 静态库
1.1. 什么是库
库是程序代码的集合,是共享程序代码的一种方式。
1.2. 库的分类
根据源代码的公开情况,库可以分为2种类型:
(1)开源库
公开源代码,能看到具体实现
比如SDWebImage、AFNetworking
(2)闭源库
不公开源代码,是经过编译后的二进制文件,看不到具体实现
主要分为:静态库、动态库
1.3. 静态库和动态库
1.3.1. 静态库和动态库的存在形式:
静态库:.a 和 .framework
动态库:.dylib 和 .framework
1.3.2. 静态库和动态库的区别:
静态库:链接时会被复制到可执行文件,被多次使用就会有多次拷贝。
动态库:链接时不会被复制到可执行文件,程序运行时由系统动态加载到内存,系统只加载一次,多个程序可共用,节省内存。
1.3.3. 补充.a与.framework 的区别:
.a 是一个纯二进制文件,不能直接拿来使用,需要配合头文件、资源文件一起使用。
.framework 中除了有二进制文件之外还有资源文件,可以拿来直接使用。
.framework = 静态库/动态库 + .h + bundle
所以,无论是 .a 静态库还是 .framework 静态库,最终需要的都是:二进制文件 + .h + 其它资源文件。
2.1. 创建.a 静态库
2.1.1. 新建项目,点击iOS — Framework&Library — Cocoa Touch Static Library
创建好后,系统自动生成以工程名命名的.h和.m文件(可删除),我们在这个自定义的目录下添加或删除文件,注意目录下Products文件夹有一个.a文件为红色,说明文件并不存在,接下来我们要做的就是把自己写的库文件中所有的.m文件都放入.a文件中私有隐藏起来。
2.1.2. 选中TARGETS下的库文件名,创建对外暴露的头文件
2.1.3 接着就可以把我们写好的代码拖进来了(在这里我把之前默认创建的两个文件删除了)
补充1:步骤2与步骤3可以对调,这边先执行步骤2的目的是为了步骤3创建文件的时候,Headers 会主动把我们新建的文件加进去,省去我们手动再去添加一次。
补充2:方法名最好加上前缀,特别是 C 的方法,避免与项目冲突。
2.1.4 暴露头文件,将我们需要暴露的头文件从 Project 里面拖到 Public
2.1.5. 编译设置:
1> 需要把 Bulid Active Architecture Only 设置为 No,Yes 表示只编译选中模拟器设备对应的架构,No则为编译所有模拟器设备支持的CPU架构。
2> 把编译模式改为Realease
3> 选择任意模拟器 Command+B,接着选择真机 Command+B,至此,已经生成我们需要的.a 文件。查看下:
2.1.6 合并真机编译生成的.a 与模拟器生成的 .a。
在终端输入以下命令行:
lipo -create 模拟器.a文件的路径 真机.a文件的路径 -output 合并后的文件名
2.1.7. 使用: 只需将IntreSDK.a和暴露出来的.h头文件导入工程目录下就可供外界使用,这样就很好的保护了自己的实现源代码。
2.2. 创建.framework 静态库
这里我以 MJRefresh 打包成静态库为例
2.2.1 创建工程,选择Cocoa Touch Framework。
创建好的工程为我们生成了如下文件,其中与工程同名的.h 文件,我们可以把所有需要导入的头文件都放在这里面。Products 文件夹下的.framework 为红色,说明还未生成。
2.2.2 导入 MJRefresh 框架中的所有文件,暴露出来的.h文件默认都在Project下,把他移到Public 下。
2.2.3 配置工程
1> 将 Build Active Architecture Only 改为 No,原因与生成.a 文件一样
2> 将Mach-O Type 改为 Static Library,我们制作的是静态.framework。
2.2.4 生成.framework 文件。先将 Run 的模式改为 Realease,分别在模拟器与真机环境下 Command+B 。编译好好原先红色的.framework 已经生成变黑。
2.2.5 合并模拟器的.framework 与真机环境的.framework。
lipo -create 模拟器MJFramework.framework的MJFramework路径 真机MJFramework.framework的MJFramework路径 -output 合并后的文件名
2.2.6 拷贝 Realease-iphoneos 文件夹下的 MJFramework.framework 至桌面,将我们刚刚合并出来的 MJFramework 替换MJFramework.framework 里的MJFramework。
2.2.7. 好了,制作完成,检查下该 .framework 是否同时支持真机与模拟器的处理器架构。
lipo -info MJFramework
说明:
模拟器:iphone4s~5 : i386
iphone5s~6plus : x86_64
真机:iphone3gs~4s : armv7
iphone5~5c : armv7s (静态库只要支持了armv7,就可以跑在armv7s的架构上)
iphone5s~6plus : arm64
armv6, armv7, armv7s是ARM CPU的不同指令集,原则是向下兼容的。例如iPhone4S CPU支持armv7, 但它同时兼容armv6,只是使用armv6指令可能无法充分发挥它的特性。
2.2.8. 将刚制作好的.Framework 导入到自己的项目中,就可以使用了。
发现如上问题(找不到该方法),因为在 MJRefresh 中包含了 Category,解决方法:
在使用静态库的工程中配置Other Linker Flags为-ObjC