1.静态库简介
1.1.静态库的简介
库就是程序代码的集合,是共享程序代码的一种方式
1.2.库的分类
(1)开源库:公开源代码,能看到具体实现
(2)闭源库:不公开源代码,是经过编译后的二进制文件,看不到具体实现;其中包括:静态库和动态库
1.3.静态库的存在形式
(1).a
(2).framework
1.4.动态库的存在形式
(1).dylib
(2).framework
1.5.静态库和动态库的区别
(1)静态库在链接时,会被完整的复制到可执行文件中,被多次使用,就有多份拷贝
(2)动态库则不会复制,只有一份,程序运行时动态加载到内存;系统只加载一次,多个程序公用,节省内存;
(3)!!!项目中如果使用到自己的动态库,不允许上架!!!,在iOS8开发了动态加载dylib的接口
1.6.静态库应用场景
(1)保护自己的核心代码,例如,国内的企业,掌握有核心技术,同时又希望更多的程序员来使用其技术,如,百度地图、友盟等
(2)将MRC的项目,打包成静态库,可以在ARC下直接使用,不需要转换
2.静态库的制作(.a)
2.1 生成静态库的步骤
(1)创建生成.a静态库的项目,如下图
(2)创建完后,如下图,添加一个log的方法
(3)选择模拟器或者Generic iOS Device, command + B,编辑,编译成功后,按照如下图的方式,查看生成的.a文件:
查看include文件,可以看到tool.h的文件,此时,如果在项目中添加一个类:Caclulate,添加一个方法 + (void)sum:(int)a b:(int)b;
如果直接编辑,那么在include文件中,不会出现Caclulate.h这个文件;
处理方式如下:
把Caclulate这个.h文件添加进入
上图中Subpath可以清空,编译后,如下图,Caclulate.h就有了:
生成的.a和.h拖入需要的工程,直接使用即可。
需要注意的一个细节是:
(1)如果生成静态库时,模拟器选择5的时候,编译,生成静态库;将.a + .h拖入需要的工程中后,运行时选择iphonXR时,就会报如下的错:
问题的原因是:
模拟器支持静态库的架构是不一样的,4s-5 的架构是i386,5s-iphoneXR支持的x86_64的架构;
真机支持静态库的架构如下,3gs-4s:armv7, 5/5c:armv7s(已弃用), 5s-iphoneXR: arm64;
查看静态库支付的架构的方法:
用终端,进入.a的文件夹,用lipo -info xxxx.a, 如下图:
不同环境下生成的静态库,一般只包含当前架构下支持的静态库,也就是在模拟器5上生成的静态库,只包含i386的架构;在5s以上生成的静态库,只包含x86_64;这样处理很麻烦,所以,我们需要在模拟器上不管选择哪个机型都可以兼容i386和x86_64。做法如下:(Build Active Architecture only:只编译活跃的静态库,即当前使用的静态库)
(可能是因为xcode更新到最新的版本,已经把i386和armv7丢弃了,所以我测试的时候,一直没有生成i386和armv7架构的静态库)
(2)目前我们生成的都是Debug版本的静态库,Debug是调试的版本;还有一个发布版本的静态库(Release版本),这两个版本的区别:
调试版本:调试版本会包含完整的符号信息,以方便调试;并且不会对代码进行优化
发布版本:不会包含完整的符号信息,执行代码是进行优化的;发布版本的大小会比调试版本的略小;发布版本在执行速度上会比较快,但是不是特别明显。
(3)如何生成Release版本的静态库:
编译,查看,就会有一个Release版本的静态库了,
我们在调试的时候,可以生成Debug的静态库,但是如果给别人的使用的话,就要提供Release版本的静态库,并且要兼容模拟器和真机的架构;
生成模拟器的静态库和真机使用的静态库前面都说过了,模拟器就选择模拟器上的任意一个机型,编辑;真机就选择Generic iOS Device,编译;
但是无论是提供模拟器还是真机的静态库,都不合适,因为模拟器的静态库只能在模拟器上使用;真机的静态库只能在真机上使用;所以,我们需要提供一个兼容模拟器和真机的静态库,方法就是合并这两个静态库,步骤如下:
第一:先各自生成模拟器和真机的静态库,如下图:
第二步:合并一个兼容模拟器和真机的静态库:
用终端进入模拟器和或者真机发布版本静态库的路径,这样,合并的静态库比较好找;如果不进入这个路径,那么合并的静态库当前默认的路径下;
用 cd + 路径,进入选中的路径,目前以进入模拟器发布版本静态库的路径为例,如下图:
然后,用命令行"lipo -create xxx1.a xxx2.a -output xxxx3.a",其中xxx1.a 表示模拟器的静态库的路径,xxx2.a表示真机的静态库的路径,xxx3.a表示合并后我们取名的静态库的名字,如下图:
上图中的hebing.a 就是我重新命名的静态库,查看behing.a的信息,可以看到如下:
以上就是生成.a的静态库的步骤。
3.生成静态库的步骤(.framework)
按照下图的方式新建一个工程:
之后就按照生成.a的静态库的步骤,即可,其中有一个主要注意的点是,如果新增.h文件,那么编译的时候,新增的.h文件不会在生成的静态库里面,所以,需要我们配置一个地方,下图表示,需要暴露的头文件添加到public上:
注意,如果在setting里面的mach-o不设置的话,会默认生成动态库,所以,做如下的修改:
生成的.framework 和生成.a的步骤都是类似的,也是模拟器的静态库支持模拟器的架构,真机的静态库支持真机的架构,如果要同时兼容,也要合并这两个静态库。
注释事项:
.a + .h +sourceFile = .Framework ,所以推荐使用framework。
但是framework有个问题,就是图片资源,需要用.boundle包含这才可以,不然添加工程中时,图片资源添加不上,需要自己手动添加。
因为Xcode默认在编译时会把所有的素材文件导入到mainBundle中,可能会使静态库的程序冲突;所以静态库中要使用图片素材时,可以利用bundle的方法。
4.静态库一边开发一边测试的方式
可以创建项目,然后往里添加一个复合项目:
目前以static Library 为例,如下:
如何现在要直接使用的话,是不可以的,需要添加两个步骤:
第一步:需要添加项目依赖,添加方式,如下:
第二步,添加链接,如下图:
之前,就可以在工程中边开发边测试了,如下图:
复合型的项目打包静态库的步骤跟之前的类似,只是需要注意,一个地方,编译之前,要选择好要编译生成静态库的工程,然后编译,如下图:
这样就可以了。
右键,show in Finder
就可以查看了