静态库知识小记

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

 

 

就可以查看了

 

posted @ 2019-10-22 19:07  一人前行  阅读(280)  评论(0编辑  收藏  举报