iOS 静态库

栏目: IOS · 发布时间: 7年前

内容简介:1.1、库:是程序代码的集合,是共享程序代码的一种方式。1.2、根据源代码的公开情况,库可以分为2种类型<1>、开源库

一、静态库简介

1.1、库:是程序代码的集合,是共享程序代码的一种方式。

1.2、根据源代码的公开情况,库可以分为2种类型

<1>、开源库

公开源代码,能看到具体实现,比如我们常见的:AFNetworking、SDWebImage、MJRefresh 等等

<2>、闭源库

不公开源代码,是经过编译后的二进制文件,看不到具体实现

主要分为:静态库、动态库

1.3、静态库和动态库的存在形式

  • 静态库:.a 和 .framework

  • 动态库:.dylib 和 .framework

1.4、静态库和动态库在使用上的区别

静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝(如下图所示)

iOS 静态库

动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存(如下图所示)

iOS 静态库

需要注意的是:项目中如果使用了自制的动态库,不能被上传到AppStore, 不允许上架!

1.5、 静态库应用场景?

  • 保护自己的核心代码,比如国内的环信,百度地图,高德地图,友盟,个推,他们掌握有核心技术,同时是又希望更多的 程序员 来使用其技术,因此采用"闭源"的方式开发使用,你只能看到他们的.h文件以及一些不重要的.m文件

  • 将 MRC 的项目,打包成静态库, 可以在ARC下直接使用, 不需要转换

1.6、静态库的特点?

  • 由 .a 和 .h 组成

  • 看不到具体实现的代码

二、.a 静态库的制作

2.1、 创建项目时, 直接选择静态库(.a)

iOS 静态库

创建项目时, 直接选择静态库(`.a`)

2.2、定义一个类方法+(void)jk_test,在.h里面暴露出来jk_test

iOS 静态库

定义一个类方法`+(void)jk_test`

2.3、添加暴露的文件

iOS 静态库

添加暴露的文件

2.4、分别在真机与6s下编译,查看生成的.a与暴露文件

iOS 静态库

分别在真机与6s下编译,查看生成的.a与暴露文件

iOS 静态库

分别在真机与6s下编译,查看生成的.a与暴露文件

2.5、新建一个工程测试 上面我们创建的 .a 文件 与 暴露文件 是否可以使用

iOS 静态库

新建一个工程测试 上面我们创建的 `.a` 文件 与 暴露文件 是否可以使用

测试结果:

1、使用6S模拟器进行测试, 可以使用

2、使用低型号模拟器测试,; 失败

3、使用真机, 编译; 失败

分析原因:原因是静态库分架构,不同的CPU架构是不一样的 ,如果 .a静态库 不支持架构,运行会报错

静态库所支持的架构

模拟器: 4s~5  : i386;5s ~ XS Max: x86_64

真机: 3gs~4s : armv7;5/5c : armv7s(armv7兼容armv7s);5s~XS Max: arm64: arm64

提示:上面的 i386、x86_64、armv7、armv7s、arm64 都是架构的名字

测试 .a静态库 所支持的架构:

cd 进入 .a静态库所在的文件夹
lipo -info 库文件

我们以上面在模拟器下的 .a静态库 为例,如下图

iOS 静态库

我们以上面在模拟器下的 `.a静态库` 为例

2.6、怎样一次编译支持多个架构的的静态库?

解决方案一:在 Build Settings ->Build Active ->NO,这样设置之后,debug真机下支持debug真机下所有的架构,debug模拟器下支持debug模拟器下所有的架构,再重复上面的测试,在iPhone5或者iPhone4下就不会报错了

iOS 静态库

在 `Build Settings` ->` Build Active` ->` NO`

注意:你的xcode要有上面架构的机型,否则只会包含有的架构,如果没有 i386架构,你可以 下载 4s~5 模拟器,再重复上面的操作

解决方案二:xcodebuild 命令行生成静态库 参考博客

debug(调试)版本

xcodebuild -target 要生成的静态库目名 -configuration Debug -sdk iphoneos -arch armv7 -arch arm64
xcodebuild -target 要生成的静态库目名 -configuration Debug -sdk iphonesimulator -arch i386 -arch x86_64

release(发布)版本

xcodebuild -target 要生成的静态库目名 -configuration Release -sdk iphoneos -arch armv7 -arch arm64
xcodebuild -target 要生成的静态库目名 -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64

提示:我们只需要生成发布版本的就好,如下步骤

# 1、cd 进入静态库项目
cd 静态库项目
# 2、操作上面 release(发布)版本 的命令

注意:在使用过 xcodebuild ,再利用 lipo -info 静态库名检测,响应的架构都支持

2.7、通过上面我们可以知道 .a静态库 在debug模式下的真机和模拟器编译各会生成一个 .a静态库,在release模式下的真机和模拟器编译也各会生成一个 .a静态库,那么我们给别人哪些 .a静态库用呢?

答案是:给其他人在release模式下的:真机与模拟器下的.a静态库

提示:.a静态库 在 测试版本 与 发布版本 的特点

  • Debug(调试版本):1、调试版本会包含完整的符号信息,以方便调试;2、调试版本不会对代码进行优化

  • Release(发布版本): 1、发布版本不会包含完整的符号信息;2、发布版本的执行代码是进行过优化的;3、发布版本的大小会比调试版本的略小;4、在执行速度方面,发布版本会更快些,但不意味着会有显著的提升

2.8、我们给用户发布版本的两个.a静态库(真机下的release模式下的.a静态库与模拟器release模式下的.a静态库),如果想要一个静态库, 既可以在模拟器上运行, 也可以在真机上运行怎么做?

答案:把发布版本的两个.a静态库合成一个 .a静态库

合并步骤:

<1>、检查发布版本的两个静态库是否支持的 架构都全

iOS 静态库

检查发布版本的两个静态库是否支持的 架构都全

<2>、合并 .a

iOS 静态库

合并 `.a`

cd 进入 Products 文件夹
lipo -create  Release-iphoneos/libJKOCProjectTool.a  Release-iphonesimulator/libJKOCProjectTool.a  -output NewJKOCProjectTool.a

提示:NewJKOCProjectTool.a 是生成的新的 .a,合成的.a的大小是合成前两个.a大小的和

<3>、合成后的.a静态库的特点

(1)、合并.a的好处,开发过程中既可以在真机上调试,也可以在模拟器上调试

(2)、 合并.a的坏处,如果静态库太大,合并打包后,会非常大,因此很多第三方的静态库的.a是区分版本的

提示:今后在使用.a静态库时一定注意版本

三、.framework 静态库的制作

3.1、创建项目时, 直接选择.framework静态库

iOS 静态库

创建项目时, 直接选择.framework静态库

3.2、创建一个继承于NSObject的JKTest类,并写一个类方法,把该类的.h文件暴露出来

iOS 静态库

创建一个继承于`NSObject`的`JKTest`类,并写一个类方法

iOS 静态库

把该类的.h文件暴露出来

3.3、利用上面2.6的方案二生成发布版本的静态库,记得修改支持的最低版本,修改 把.framework的库由动态库改为静态库

iOS 静态库

修改支持的最低版本

iOS 静态库

修改 把`.framework`的库由 动态 改为 静态库 

// 1.cd 进入静态库项目
cd JKOCProjectTool
// 2.使用xcodebuild生成静Release下真机的静态库
xcodebuild -target JKOCProjectTool -configuration Release -sdk iphoneos -arch armv7 -arch arm64
// 3.使用xcodebuild生成静Release下模拟器的静态库
xcodebuild -target JKOCProjectTool -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64

iOS 静态库

使用xcodebuild生成静Release下模拟器的静态库

提示:你如果需要 Debug 下的静态库,参照 2.6 自行生成

3.4、测试一下是否可以运行(提示:如果不把动态库改为静态库会运行报错,如果你想强行使用动态库,那么你就在:TARGETS->General->Embedded Binaries 添加你的库)

iOS 静态库

测试OK

3.5、合并 .framework 静态库

iOS 静态库

合并静态库

lipo -create 真机的JKOCProjectTools路径 模拟器的JKOCProjectTools路径 -output 合并后的JKOCProjectTools文件

切记:合成的是二进制文件而不是framework,最后合成的二进制文件替代之前的二进制文件即可

四、总结

4.1、静态库打包的完整正确步骤

<1>、确定是静态库

.a 的肯定是静态库

.framework的需要设置链接类型,project -> Build Settings-> 搜索 Mach-o Type ; 改为静态库选择 Static Library

iOS 静态库

`.framework`的需要设置链接类型

<2>、确定支持模拟器或者真机中的所有架构

  • 如果使用的2.6类里面的 方案一 那就是xcode要支持所有的架构的模拟器,并且修改 Build Settings ->Build Active ->NO,这样编译之后,debug真机下支持debug真机下所有的架构,debug模拟器下支持debug模拟器下所有的架构

  • 如果使用的2.6类里面的 方案二 xcodebuild方法就可以支持所有的架构

<3>、提供的静态库应该是 release版本

  • 如果使用的2.6类里面的 方案一:项目 -> Edit Scheme -> Run -> Release/Debug 分别进行编译

  • 如果使用的2.6类里面的 方案二 xcodebuild方法,在命令类里面输入 Release 就好

4.2、.a静态库和.framework静态库的区别?

<1>、.a 是一个纯二进制文件,  .framework中除了有二进制文件之外还有资源文件,.bundle就是资源文件

<2>、.a 文件不能直接使用, 至少要有.h文件的配合; .framework 文件可以直接使用

<3>、.a + .h + sourceFile = .framework

<4>、建议使用 .framework

4.3、静态库开发中的常见问题

问题1: 有些第三方库会使用到一些图片素材,例如公司的logo,xib文件等,如何做?

答:创建一个.bundle文件,创建方式看 资源文件 .buldle 的添加第十。

问题2: 如果用户需要导入的头文件过多怎么加?

答:在创建  .framework项目会默认生成一个 .h 文件,我们可以把其他的 .h 文件导入 默认生成一个.h 文件 中

问题3: 静态库程序怎样测试?

答:创建一个创建复合项目,看下面 4.4 创建的步骤

4.4、创建一个创建复合项目(符合工程的名字定义为:复合项目)

<1>、在复合项目中添加一个.framework的静态库JKTools

iOS 静态库

在复合项目中添加一个`.framework`的静态库`JKTools`

<2>、创建一个JKTest类,创建一个类方法,并把JKTest的.h放到创建静态库生成的.h文件里面

iOS 静态库

创建一个`JKTest`类,创建一个类方法

iOS 静态库

把JKTest的`.h`放到创建静态库生成的`.h`文件里面

<3>、选中JKTools,修改下面选项

iOS 静态库

修改JKTools支持的最低版本为9.0,看自己项目了

iOS 静态库

设置为静态库

iOS 静态库

修改 Build Settings ->Build Active ->NO,这样编译之后,debug真机下支持debug真机下所有的架构,debug模拟器下支持debug模拟器下所有的架构 iOS 静态库

把需要暴露的文件放到Public里面

<4>、在符合项目添加我们的静态库依赖

iOS 静态库

在符合项目添加我们的静态库依赖

<5>、测试

导入#import ,调用下面的方法

[JKTest jk_test];

打印结果:

复合项目的测试

<6>、有关 .framework的文件导出,我就不再重复了,也就是上面2.6的步骤,有关合上面也有讲述

五、将MRC的项目,打包成静态库, 可以在ARC下直接使用, 不需要转换

5.1、应用场景

你找到一个功能是ARC项目下的,你想用,里面有很多的类,你怎么把他们搬到ARC项目下使用???

5.2、解决方案一(适用于类不太的情况)

<1>、我们模拟一个类JKTools,它是MRC下的项目

iOS 静态库

我们模拟一个类JKTools,它是MRC下的项目

<2>、我们把JKTools的.h与.m拖到ARC的工程下,报错是肯定的,我们看下如何处理。如下图 iOS 静态库

在ARC图中路径找到MRC下的.m文件,双击输入-fno-objc-arc

提示:在ARC图中路径找到MRC下的.m文件,双击输入-fno-objc-arc,再运行就不会报错了

5.3、解决方案二(适用于MRC的类很多的情况):把MRC下的类打包成静态库,.a 或者 .framework 都可以,下面以打包成.framework为例,步骤如下

<1>、创建一个.framework项目,这里名字一JKTools为例,把上面JKTools.h和JKTools.m拖进去,把并修改项目为 MRC iOS 静态库

修改项目为MRC

在TARGETS->Build Settings下搜 Automatic Reference ,改为 NO;其中YES为ARC,NO为MRC。

<2>、重复 4.4 里面<3>的步骤

<3>、生成发布版本的静态库以及合并真机与模拟器的二进制文件,最后把合并的二进制文件替换掉 真机下framework里面的二进制文件

<4>、把framework拖入 ARC的项目,直接导入framework里面的.h文件查看是否可以,经过测试时OK的,不懂的你可以联系我

五、Swift打包动态库

5.1、创建一个Swift 下的 .framework 工程,命名为 JKTools ,同时创建一个类JKTest,写一个方法 jk_test

iOS 静态库

创建一个`Swift` 下的 `.framework` 工程,命名为 `JKTools` ,同时创建一个类`JKTest`,写一个方法 `jk_test`

5.2、把支持的最低版本调为 9.0,具体的看自己项目

iOS 静态库

把支持的最低版本调为 9.0,具体的看自己项目

5.3、修改 Build Settings ->Build Active ->NO,这样编译之后,debug真机下支持debug真机下所有的架构,debug模拟器下支持debug模拟器下所有的架构

5.4、修改 为静态库

iOS 静态库

修改 为静态库

5.5、在release下编译模拟器与真机,生成像一个的.framework 文件,把类里面的二进制文件合并成一个,步骤和上面一样,不再重复了

5.6、测试静态库的使用,结果显示是OK的 iOS 静态库

测试静态库的使用,结果显示是OK的

到此,静态库的相关知识记录到这,相比较其他的博客还是比较详细的。遇到任何问题都可以再我的个人信息里面来联系我

作者:IIronMan

链接:https://www.jianshu.com/p/d79f6c866fdb


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入分析Java Web技术内幕(修订版)

深入分析Java Web技术内幕(修订版)

许令波 / 电子工业出版社 / 2014-8-1 / CNY 79.00

《深入分析Java Web技术内幕(修订版)》新增了淘宝在无线端的应用实践,包括:CDN 动态加速、多终端化改造、 多终端Session 统一 ,以及在大流量的情况下,如何跨越性能、网络和一个地区的电力瓶颈等内容,并提供了比较完整的解决方案。 《深入分析Java Web技术内幕(修订版)》主要围绕Java Web 相关技术从三方面全面、深入地进行了阐述。首先介绍前端知识,即在JavaWeb ......一起来看看 《深入分析Java Web技术内幕(修订版)》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具