Xcode7 中建立静态库:.a 和 .framework html
1、简单介绍架构
1.什么是库?框架
库是程序代码的集合,是共享程序代码的一种方式iphone
2.库的分类工具
根据源代码的公开状况,库能够分为2种类型性能
(1)开源库测试
公开源代码,能看到具体实现ui
好比SDWebImage、AFNetworkingspa
(2)闭源库命令行
不公开源代码,是通过编译后的二进制文件,看不到具体实现
主要分为:静态库、动态库
2、静态库和动态库
1.静态库和动态库的存在形式
静态库:.a 和 .framework
动态库:.dylib 和 .framework
2.静态库和动态库在使用上的区别
静态库:连接时,静态库会被完整地复制到可执行文件中,被屡次使用就有多份冗余拷贝(图1所示)
动态库:连接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存(图2所示)
3、静态库简介:
一、静态库分为:
真机—Debug(调试)版本、
真机—Release(发布)版本、
模拟器—Debug版本、
模拟器—Release版本;
开发中通常都打包Release(发布)版本,将真机和模拟器版本合并,提供外界。
二、使用场景:在项目开发的过程当中,例如两个公司之间业务交流,不可能把源代码都发送给另外一个公司,这时候将私密内容打包成静态库,别人只能调用接口,而不能知道其中实现的细节。
4、用Xcode7建立.a静态库
.a文件版本(以制做SDWebImage静态库为例)
一、新建项目,点击iOS—Framework&—Cocoa Touch Static Library。
给你的工程命名为SDWebImageStaticLib
二、系统自动生成以工程名命名的.h和.m文件,可自定义的在目录下添加或删除文件,注意目录下Products文件夹有一个.a文件为红色,说明文件并不存在,须要接下来的处理就是将是本身写的库文件中全部的.m文件都放入.a文件中私有隐藏起来。
这里咱们将系统生成的.h和.m文件删除。
3.选中TARGETS下的库文件名,建立对外暴露的头文件
建立完以后
4.将SDWebImage下的全部文件导入到SDWebImageStaticLib下
注意:第三步骤和第四步骤是能够调换的,只不过调换后须要手动的将须要暴露的头文件添加进去,因此不调换能够帮助咱们完成。
此时默认的状况下,暴露的头文件都在Project下,应该移动到Public下
以前:
移动后:
五、而后点击左上角,选择Edit Scheme,Build Configuration下选择Release,先注意检查下面Release是否为NO:Yes表示只编译选中模拟器设备对应的架构,No则为编译全部模拟器设备支持的cup架构(Debug版本同理),选择NO,而后分别在模拟器和真机下Command+B编译一下,会看到Products文件夹下的.a文件变为黑色,这个.a文件就是咱们想要获得的静态库,这里会出现一个问题你先编译的模拟器会发现.a依然是红色,你须要模拟器和真机都编译后.a才会变成黑色,这应该是Xcode自己的问题。
<1>
<2>
<3>
这3步设置完后,选择真机模式编译一下,Command + B,此时看到.a静态库文件变成了黑色。
而后将上面的第<3>步改成Debug,再选择模拟器编译一下,Command + B,就建立了模拟器环境下的.a文件,截图以下同样。
能够在终端看到,真机Release发布模式和模拟器Debug测试模式的.a文件都存在
文件为:
六、合并真机和模拟器.a文件,在终端输入如下命令行:lipo -create 模拟器.a文件的路径 真机.a文件的路径 -output 合并后的保存路径(最终会获得一个合并后的libSDWebImageStaticLib.a文件,再将暴露出来的.h头文件一块儿复制出来。
七、使用:只需将libSDWebImageStaticLib.a和暴露出来的.h头文件导入工程目录下就可供外界使用,这样就很好的保护了本身的实现源代码,不被他人篡改和偷窃。
8.这里再补充一下:
<1>.文件大小.a文件的体积(通常状况下)
真机用的.a > 模拟器用的.a
所合成.a == 真机用的.a + 模拟器用的.a
<2>.
注:关于静态库对CPU架构的支持,首先了解iOS设备CPU架构方面的知识,ARM是微处理器行业的一家知名企业,arm处理器以体积小和高性能的优点在嵌入式设备中普遍使用,几乎全部手机都是使用它的。
模拟器: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指令可能没法充分发挥它的特性。
查看静态库.a对处理器架构的支持,先cd到.a文件的路径下,命令行输入:lipo -info xxxxx.a
<3>.
若是库中还包含了一些资源文件(如图片等),那么资源文件也应该放在上面的文件夹中。
5、用Xcode7建立.framework静态库,以MJRefresh为例
1.新建工程并选择默认Target为Cocoa Touch Framework, 如图:
2.给你的工程命名为MJRefresh,生成的静态库将以标准的名称格式出现.即MJRefresh.framework
三、项目自动建立设置开放的头文件和存放资源的Bundle文件,能够看到一个红色的MJRefresh.framework空的静态库
四、删除自动生成的MJRefresh.h文件
五、导入MJRefresh框架中的全部文件,应该暴露出来的.h文件默认都在Project下
六、.framework中有些类多是一些私有的辅助工具,不须要使用者看到,在这里只须要把开放出去的类放到Public下, 如图
七、而后选择模拟器和Debug模式,编译一下,Command + B,此时,虽然看到MJRefresh.framework仍为红色,其实已经生成能在模拟器上运行的.framework静态库,进入MJRefresh.framework目录文件下,以及使用终端能够看到生成的静态库。
选中静态库文件,获取绝对路径以下:
在目录下和终端能够看到生成的静态库
八、再选择真机,设置Release模式,编译一下,Command + B,此时,虽然看到MJRefresh.framework变成黑色,生成能在真机上运行的静态库文件。
在目录下和终端能够看到生成的静态库
九、咱们随意选择一个静态库,点进去看这个库文件中的具体内容,能够看到一个MJRefresh可执行二进制的文件,资源MJRefresh.bundle,暴露出去的头文件Headers等
十、下面一步就是合并了,生成模拟器和真机环境下通用的二进制可执行文件MJRefresh,生成后看一下这个可执行文件使用的微处理器架构有哪些:
11.好了,合并替换完成,剩下的就是如何使用这个最终的MJRefresh.framework静态库了。
(1)咱们能够随意选择一个生成的MJRefresh.framework,拷贝一下到桌面
(2)而后再将合并后生成的可执二进制文件MJRefresh拷贝一下,粘贴到桌面上这个MJRefresh.framework文件中,替换里面的MJRefresh,生成一个完成的静态库。
(3)打开MJRefresh.framework/Modules/module.modulemap文件,能够看到暴露的MJRefrsh.h文件被放在umbrella雨伞下保护起来了,因此咱们须要将其余的全部暴露的.h文件放到MJRefresh.h文件中保护起来,否则会出现警告
(4)咱们觉得此时大功告成,能够测试代码了,结果出现以下错误:
为何会这样的?由于咱们作的是静态库,在使用的时候须要额外加一个步骤,要把Framework同时添加到‘Embedded Binaries’中
此时再测试,发现没问题了,大功告成,可喜可贺!
6、制做静态库的注意点
(1)注意:
不管是 .a 静态库仍是 .framework 静态库,最终须要的都是:二进制文件 + .h + 其它资源文件
(2).a 和 .framework 的使用区别
.a 自己是一个二进制文件,须要配上 .h 和 其它资源文件 才能使用
.framework 自己已经包含了 .h 和 其它资源文件,能够直接使用
(3)图片资源的处理
若是静态库中用到了图片资源,通常都放到一个bundle文件中,bundle名字通常跟 .a 或 .framework 名字一致
bundle的建立:新建一个文件夹,修改扩展名为 .bundle 便可,右击bundle文件,显示包内容,就能够往bundle文件中放东西
建议:本身制做的静态库中要用到的图片资源,不建议直接以png的后缀名方式拖到项目中使用,而是推荐使用放到bundle文件中。这样能够避免静态库的图片名和使用静态库的项目中存在的图片产生冲突。
1)新建一个文件夹,把须要打包的资源图片放在里面
例如:
2)修改扩展名为 .bundle,敲回车,点击添加。
例如:
(4)多文件处理
若是静态库须要暴露出来的 .h 比较多,能够考虑建立一个主头文件(通常 主头文件 和 静态库 同名)
在主头文件中包含全部其余须要暴露出来的 .h 文件
使用静态库时,只须要#import 主头文件
实际上苹果官方就是这么作的,例如:#import <UIKit/UIKit.h>
(5).framework为何既是静态库又是动态库
系统的 .framework 是动态库
咱们本身创建的 .framework 是静态库
(6)静态库中包含了Category(分类)
若是静态库中包含了Category,有时候在使用静态库的工程中会报“方法找不到”的错误(unrecognized selector sent to instance)
解决方案:在使用静态库的工程中配置Other Linker Flags为-ObjC