iOS创建静态库(Xcode8 )

一、简单介绍

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


1.png
2.png

创建好后,系统自动生成以工程名命名的.h和.m文件(可删除),我们在这个自定义的目录下添加或删除文件,注意目录下Products文件夹有一个.a文件为红色,说明文件并不存在,接下来我们要做的就是把自己写的库文件中所有的.m文件都放入.a文件中私有隐藏起来。


3.png

2.1.2. 选中TARGETS下的库文件名,创建对外暴露的头文件


4.png
5.png

2.1.3 接着就可以把我们写好的代码拖进来了(在这里我把之前默认创建的两个文件删除了)


6.png
补充1:步骤2与步骤3可以对调,这边先执行步骤2的目的是为了步骤3创建文件的时候,Headers 会主动把我们新建的文件加进去,省去我们手动再去添加一次。
补充2:方法名最好加上前缀,特别是 C 的方法,避免与项目冲突。

2.1.4 暴露头文件,将我们需要暴露的头文件从 Project 里面拖到 Public

![7.png](http://upload-images.jianshu.io/upload_images/449463-cdaa4444be27c364.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.1.5. 编译设置:
1> 需要把 Bulid Active Architecture Only 设置为 No,Yes 表示只编译选中模拟器设备对应的架构,No则为编译所有模拟器设备支持的CPU架构。


8.png

2> 把编译模式改为Realease

9.png

10.png

3> 选择任意模拟器 Command+B,接着选择真机 Command+B,至此,已经生成我们需要的.a 文件。查看下:

11.png
12.png

2.1.6 合并真机编译生成的.a 与模拟器生成的 .a。
在终端输入以下命令行:

lipo -create  模拟器.a文件的路径 真机.a文件的路径 -output 合并后的文件名
13.png

2.1.7. 使用: 只需将IntreSDK.a和暴露出来的.h头文件导入工程目录下就可供外界使用,这样就很好的保护了自己的实现源代码。

14.png

2.2. 创建.framework 静态库

这里我以 MJRefresh 打包成静态库为例
2.2.1 创建工程,选择Cocoa Touch Framework。


Snip20170121_1.png
Snip20170121_2.png

创建好的工程为我们生成了如下文件,其中与工程同名的.h 文件,我们可以把所有需要导入的头文件都放在这里面。Products 文件夹下的.framework 为红色,说明还未生成。


Snip20170121_4.png

2.2.2 导入 MJRefresh 框架中的所有文件,暴露出来的.h文件默认都在Project下,把他移到Public 下。

Snip20170121_22.png
Snip20170121_5.png

2.2.3 配置工程
1> 将 Build Active Architecture Only 改为 No,原因与生成.a 文件一样


Snip20170121_6.png

2> 将Mach-O Type 改为 Static Library,我们制作的是静态.framework。


Snip20170121_7.png

2.2.4 生成.framework 文件。先将 Run 的模式改为 Realease,分别在模拟器与真机环境下 Command+B 。编译好好原先红色的.framework 已经生成变黑。


![ ![Snip20170121_10.png](http://upload-images.jianshu.io/upload_images/449463-c875a00248c3d5dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](http://upload-images.jianshu.io/upload_images/449463-023077392ace4ed8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.2.5 合并模拟器的.framework 与真机环境的.framework。

lipo -create  模拟器MJFramework.framework的MJFramework路径 真机MJFramework.framework的MJFramework路径 -output 合并后的文件名
Snip20170121_12.png
Snip20170121_18.png
2.2.6 拷贝 Realease-iphoneos 文件夹下的 MJFramework.framework 至桌面,将我们刚刚合并出来的 MJFramework 替换MJFramework.framework 里的MJFramework。

2.2.7. 好了,制作完成,检查下该 .framework 是否同时支持真机与模拟器的处理器架构。

lipo -info MJFramework
Snip20170121_21.png

说明:

模拟器: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 导入到自己的项目中,就可以使用了。


Snip20170121_25.png

发现如上问题(找不到该方法),因为在 MJRefresh 中包含了 Category,解决方法:
在使用静态库的工程中配置Other Linker Flags为-ObjC

Snip20170121_27.png

大功告成!

推荐阅读更多精彩内容

  • 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别...
    吃瓜群众呀阅读 3,950评论 3 26
  • 这几天公司有一个新的需求,就是要将我们开发的某些东西都抽取出来,打个比方我们开发了A项目,可以以后B项目要包含A项...
    黄鱼儿啦啦啦阅读 2,245评论 2 16
  • 介绍 动态库形式:.dylib和.framework 静态库形式:.a和.framework 动态库和静态库的区别...
    齐滇大圣阅读 15,414评论 11 120
  • 仅以方便自己查阅记录前言1.静态库和动态库有什么异同?静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗...
    190CM阅读 1,093评论 0 2
  • 回忆这种东西真奇妙,它无声又无息,悄悄的就来了。有的回忆是美好的,有的回忆是痛苦的。而我们要放弃的是那些痛苦。...
    梦回昨日阅读 29评论 0 0