IOS 打包静态库详细介绍

IOS 打包静态库详细介绍

一、前言

前段时间看的一本书上说:“隔着一段距离看,很多有趣的知识看起来都很唬人。”比如说这篇我要总结的“静态库知识”,在我初出茅庐的时候着实觉得那些后缀名为“.frameworke”、“.a”、“.dylib”的文件很神秘,很高冷。那时我虽然知道只要导入一个库就能引用库里面很多封装好的东西,但对这个“库”究竟是什么“鬼”,一直都是云里雾里。好了废话不多说,看下去就知道它是个什么“鬼”。

二 、一些概念的补充

1、 什么是库?

所谓库就是程序代码的集合,是共享程序代码的一种方式。

2、 库的分类

根据程序代码的开源情况,库可以分为两类

开源库

源代码是公开的,你可以看到具体实现。比如GitHub上比较出名的第三方框架AFNetworking、SDWebImage。

闭源库

不公开源代码,只公开调用的接口,看不到具体的实现,是一个编译后的二进制文件。这种常见于一些公司的SDK包,比如高德地图SDK、环信即时通讯SDK等等。而闭源库又分为两类:静态库和动态库。本篇重点要讲的便是其中的静态库。

3、静态库和动态库的存在形式和使用区别

存在形式:

静态库

以".a"或者“.framework”为文件后缀名

动态库

以".dylib"或者“.framework”为文件后缀名

使用区别:

静态库链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝。

静态库被程序使用时

动态库链接时不复制,程序运行时由系统动态加载到内存,供程序调用。而且系统只加载一次,多个程序共用,节省内存。

动态库被程序使用时

4、iOS 设备的CPU架构

模拟器:
4s-5: i386
5s-7 Plus: x86_64

真机(iOS设备):
armv6: iPhone、iPhone 2、iPhone 3G、iPod Touch(第一代)、iPod Touch(第二代)
armv7: iPhone 3Gs、iPhone 4、iPhone 4s、iPad、iPad 2
armv7s: iPhone 5、iPhone 5c (静态库只要支持了armv7,就可以在armv7s的架构上运行)
arm64: iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3

:真机iPhone7、iPhone7 Plus A10处理器到底是什么架构暂时不得而知,没查到相关资料,貌似还没公布,但是模拟器是x86_64。

三、打包静态库

因为静态库存在两种形式,我们先看.a静态库的打包

.a文件静态库打包

1、打开Xcode创建一个新的工程,这里以Xcode8为例,选择工程如下:

创建一个新的工程

2、创建工程完毕后,再创建一个工具类StaticLibTool,添加一个方法用于测试

创建一个工具类,添加测试方法

StaticLibTool.m文件实现如下

taticLibTool.m文件实现

3、运行工程进行打包

运行工程打包

运行完毕后,我们会看到工程中Products文件夹下的libStaticLib.a文件由红色变成了黑色。右键show in finder可以在其目录下找到它。这就是我们打包好的.a静态文件了。

打包好的.a静态文件

但是这样就完了吗?当然没有,我们知道静态库存在的最大意义是隐藏代码的具体实现,但是这也隐藏的太彻底了,总要公开些接口或者头文件供人调用吧。

4、公开接口头文件

targets->Build Phases->Copy Files->"+"你需要公开的头文件

这里我们把新建的测试类StaticLibTool.h公开

公开接口头文件

公开头文件后,我们再按上述1、2、3流程重新运行打包,我们会得到一个头文件和一个.a静态库(如下图),而这正是我们所需要的。

重新运行打包

5、新建一个可运行的工程,把这两个打包好的文件拖入项目测试

测试

选择Iphone7模拟器运行,程序正常运行,点击模拟器屏幕,打印日志如下:

日志输出

我们可以看到输出没有问题,打包.a静态库大功告成。

但是,别高兴的太早。当我把模拟器切换成Iphone5运行时,编译直接不通过,报错如下:

iPhone 5模拟器运行时的编译错误

上图“Undefined symbols for architecture i386”是什么意思呢?意思是我们的libStaticLib.a静态库不支持i386架构。那i386又是什么鬼?不清楚的可以拉上去看“iOS 设备的CPU架构”,这里就不多做解释了。

iPhone 5模拟器正好是i386架构,而我们打包的静态库不支持。但是iPhone 7模拟器运行却没有问题,这说明我们打包的静态库正好支持iPhone 7模拟器 的cpu架构 x86_64。如何查看静态库所支持的架构,请看下一步。

6、终端查看静态库所支持的架构

终端->cd进入库文件路径->lipo -info 库名

终端查看静态库所支持的架构

上图可以看到,我们的静态库仅支持x86_64架构,也就是说此静态库只可运行在iphone5s-iphone7plus之间的模拟器设备。所以刚才我们运行iphone5模拟器时,编译会报错。

到这里就可以进一步解释下,打包静态库时,你用什么模拟器运行,打包出来的静态库就支持什么模拟器的架构,而刚才我打包时是用iPhone7运行,所以仅支持架构x86_64。那么这就太麻烦了,可以打包一个静态库支持多种架构的模拟器吗?答案是肯定的,请看下一步。

7、设置适配所有模拟器架构

project -> buildSeting -> Build Active Architecture Only 设为NO

设置适配所有模拟器架构

设置完成后,我们重新运行打包静态库文件(这时你可随便选一个模拟器),按照上述第6步终端查看其支持的架构,我们可以看到终端输出的结果是同时支持 i386和x86_64,这也就意味着同时支持所有模拟器。

到这里打包.a静态库已经告一段落,但是按上述流程打包的只能在模拟器上跑,真机是不能运行的,因为ios真机设备跟模拟器的架构又不一样(怎么不一样自己拉上去看),所以还没完(我也不想啊 ),请看下一步

8、打包支持真机架构的静态库

所有流程都跟上面的一样,只是我们运行打包时要选择真机运行,如下图你可以选择自己插上去的真机,也可以选择Generic ios Devices。当然不要忘记了设置支持所有真机机型架构: Build Active Architecture Only 设为NO。

打包支持真机架构的静态库

我们可以看下打包出来的终端查看结果如下:

终端输出结果

上图可以看到同时支持armv7和arm64,也就是支持所有ios设备。好了到此打包.a静态库算是告一段落。

.frameworke文件静态库打包

1、依然Xcode创建一个新的工程FrameworkeLib,选择工程如下:

创建一个新的工程

创建完成后我们可以看到,工程本身自带一个FrameworkeLib.h文件,这是类似一个主头文件一样的东西

FrameworkeLib.h文件

2、创建需要测试的类,为了方便我把上述打包.a的测试类StaticLibTool直接拖来使用。

3、设置支持所有模拟器架构或真机架构(和打包.a第7步骤一样)

4、公开头文件

target-Build Phases - Headers -把需要公开的头文件从project拖入Public

暴露头文件

5、设置打包的是静态库。因为动态库也可以是以framework形式存在,所以需要设置,否则默认打出来的是动态库

target->BuildSetting ->搜索关键字mach->Mach-o Type 设为Static Library(这个默认选项是动态的)

设置打包的是静态库

6、选中真机或模拟器运行设备打包(与打包.a一样),完成后Products文件夹下的FrameworkeLib.framework文件由红色变成了黑色,右键show in finder 显示如下:

打包结果

FrameworkeLib.framework拖入项目便可直接使用,这里就不再进行测试了。此外还要补充的一点是,打包静态库的时候还需注意打包的是测试版(Debug)还是发布版(Release),这个根据你自己的需求决定,而如何进行设置请下一步骤。

7、设置打包静态库的测试版和发布版(.a和.frameworke)

product -> scheme -> Edit scheme -> Run->选择Debug或Release

设置版本

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • iOS中打包上传常见的错误与解决办法

    一.ERROR ITMS-90535 首先这个原因导入了其他第三方导致的问题,首先找到友盟库里面的腾讯API,找到其中的info.plist文件: 找到箭头所指向的一行,随后删掉 这一行 就可以了: 二.ERROR ITMS-90635 这个是由于项目中有使用到Cocoapods导入第三方的库使用bitcode造成的,此种错误我在网上找到了三种解决办法: 方法一 项目->targets->enable bitcode->no pods->project->enable bit

  • IOS 静态库打包流程简化详细介绍

    IOS 静态库打包流程简化 在iOS开发中,我们经常会遇到开发SDK的需求.开发好的静态库后需要手动的合并.a文件,然后再拷贝相关的头文件,接着把静态库和头文件放在同一个文件里面打包发送给SDK的使用者.本文将介绍如何使用脚本,简化这一连串的过程.为了照顾广大初学者,教程将会详细介绍打包的基本流程. 关于静态库和动态库区别,可以看我的另外一篇文章: iOS静态库和Framework区别 项目配置 新建一个名为TestSDK的静态库工程 然后点击Target下边的加号按钮,添加新的Target 选

  • IOS 打包出现Missing Push Notification Entitlement 问题解决方案

    Missing Push Notification Entitlement 问题 最近打包上传是遇到一个问题: 描述: Missing Push Notification Entitlement - Your app includes an API for Apple's Push Notification service, but the aps-environment entitlement is missing from the app's signature. To resolve th

  • IOS 打包静态库详细介绍

    IOS 打包静态库详细介绍 一.前言 前段时间看的一本书上说:"隔着一段距离看,很多有趣的知识看起来都很唬人."比如说这篇我要总结的"静态库知识",在我初出茅庐的时候着实觉得那些后缀名为".frameworke".".a".".dylib"的文件很神秘,很高冷.那时我虽然知道只要导入一个库就能引用库里面很多封装好的东西,但对这个"库"究竟是什么"鬼",一直都是云里雾里

  • iOS 配置.gitignore文件详细介绍

    iOS 配置.gitignore文件详细介绍 为什么要配置.gitigore 在我们使用git的过程当中,不是任何文件都需要commit到本地或者远程仓库的,比如一些三方库文件. 那么作为一个git新手,很多人不知道如何配置.gitignore文件,本文只是提供一个便捷的例子.你可以直接使用本文提供的代码编辑到你的.gitigore文件中. 简便配置 直接复制下面的内容到你的.gitignore文件即可.注意,这个配置是给iOS开发者使用的. # Xcode .DS_Store */build/

  • Gradle编译打包Android apk详细介绍

    Gradle编译打包Android apk详细介绍 理解Gradle构建过程,解读Android Gradle插件的配置 阅读本文一定是要使用过Gradle生成apk,文中不会讲如何安装运行Gradle,如有需要可先看文末的参考文章. APK包是一个ZIP压缩包,从Java源代码.资源文件到生成这个APK,经过了编译打包一系列特定的过程,SDK文档(/docs/tools/building/index.html)中找到.而这一系列特定的过程,重复繁琐,构建工具(build tool)就是来流程化

  • IOS 字符串常用处理详细介绍

    IOS 字符串常用处理详细介绍 NSString *tempA = @"123"; NSString *tempB = @"456"; 1,字符串拼接 NSString *newString = [NSString stringWithFormat:@"%@%@",tempA,tempB]; 2,字符转int int intString = [newString intValue]; 3,int转字符 NSString *stringInt =

  • C++的sstream标准库详细介绍

    C++的sstream标准库介绍 接下来我们继续看一下C++风格的串流控制 ,C++引入了ostringstream.istringstream.stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件. istringstream类用于执行C++风格的串流的输入操作. ostringstream类用于执行C风格的串流的输出操作. strstream类同时可以支持C风格的串流的输入输出操作. istringstream类是从istream(输入流类)和strings

  • Lua中os库详细介绍

    这个库通过表os实现 os.clock () 功能:返回一个程序使用CPU时间的一个近似值 例如: 复制代码 代码如下: local x = os.clock(); print(os.clock()) local s = 0; for i = 1, 100000000 do       s = s + i; end print(string.format("elapsed time : %.2f\n", os.clock() - x)); 输出: 复制代码 代码如下: 0 elapse

  • iOS Mask属性的详细介绍及应用实例

    前言: 在开发过程中,类似android和其他平台的UI开发方法,需要通过一个mask图显示部分UI或者Icon资源.ios的控件自带alpha的值,但是这个值都是整个icon或者UI的透明效果,不能做到自定义的透明或者镂空效果.我们必须借助于mask资源图. Mask属性介绍 Mask平时用的最多的是masksToBounds 吧. 其实除此以外Mask使用场景很多,看完之后你会发现好真是好用的不要不要的... 先来了解下Mask属性到底是什么? Mask 英文解释是蒙板/面罩,平时我们称为蒙

  • iOS开发 正则运算详细介绍

    iOS开发 正则运算 1. 正则运算意义 regular expression 描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串等,而在iOS 中我们多数用于检查字符串是否符合规则 2. 常用正则表达式 (如果想自己动手写出符合需求的正则表达式,只需了解 4 中的符号意义) (1).用户名 "^[a-zA-Z][a-zA-Z0-9_]{5,15}$" (由6-16位字母数字下划线组成,第一位不能为数字或下划线) [a

  • 代理角色java设计模式之静态代理详细介绍

    Java动态代理模式 代理:一个角色代表别一个角色来实现某些特定的能功.    比如:生产商,中间商,客户这三者这间的关系              客户买产品不并直接与生产商打交道,也用不晓得产品是如何生产的,客户只与中间商打交道,而中间商便可以对产品行进一些包装,供提一些售后的服务. 代理模式有三个角色: 1. 抽象主题角色 2. 代理主题角色 3. 际实被代理角色 面下我们来个一个静态代理的现实. 我以一个坦克为例. 抽象主题角色:Moveable 复制代码 代码如下: package c

随机推荐