登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

iOS 静态库相关分析 [复制链接]

2019-2-12 10:47
James1991 阅读:107 评论:0 赞:0
Tag:  

一、静态库简介

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

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

<1>、开源库

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

<2>、闭源库

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

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

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

  • 静态库:.a 和 .framework

  • 动态库:.dylib 和 .framework

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

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

image.png

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

image.png

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

1.5、 静态库应用场景?

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

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

1.6、静态库的特点?

  • 由 .a 和 .h 组成

  • 看不到具体实现的代码

二、.a 静态库的制作

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

image.png

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

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

image.png

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

2.3、添加暴露的文件

image.png

添加暴露的文件

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

image.png

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

image.png

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

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

image.png

新建一个工程测试 上面我们创建的 `.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静态库 所支持的架构:

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

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

image.png

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

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

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

image.png

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

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

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

debug(调试)版本

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

release(发布)版本

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

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

1
2
3
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>、检查发布版本的两个静态库是否支持的 架构都全

image.png

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

<2>、合并 .a

image.png

合并 `.a`

1
2
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静态库

image.png

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

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

image.png

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

image.png

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

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

image.png

修改支持的最低版本

image.png

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

1
2
3
4
5
6
// 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

image.png

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

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

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

image.png

测试OK

3.5、合并 .framework 静态库

image.png

合并静态库

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

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

四、总结

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

<1>、确定是静态库

.a 的肯定是静态库

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

image.png

`.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

image.png

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

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

image.png

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

image.png

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

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

image.png

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

image.png

设置为静态库

image.png

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

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

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

image.png

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

<5>、测试

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

1
[JKTest jk_test];

打印结果:

1
复合项目的测试

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

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

5.1、应用场景

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

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

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

image.png

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

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

在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拖进去,把并修改项目为 MRCimage.png

修改项目为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

image.png

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

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

image.png

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

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

5.4、修改 为静态库

image.png

修改 为静态库

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

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

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

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

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)
关闭

每日2018年最新白菜彩金

通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

返回顶部
博聚网