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。

5、a与.framework有什么区别?

.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。

.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。

.a + .h + sourceFile = .framework。

建议用.framework.

6、制作静态库时的几点注意:

1 注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件+.h+其它资源文件的形式,不同的是,.a本身就是二进制文件,需要我们自己配上.h和其它文件才能使用,而.framework本身已经包含了.h和其它文件,可以直接使用。

2 图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。

3 category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC。

4 如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。


三、进入主题:打包静态库!

.a文件静态库打包

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

创建一个新工程

2、创建工程完毕后,界面如下(以打包SDWebImage为例)


系统会默认帮我们生成两个文件,可以只留一个.h文件然后把SDWebImage框架的所有文件拖拽到工程里面,然后把想暴露的头文件写在SDWebImage.h里面(也可以俩个文件都删除,把框架的文件都拖拽进去)。

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

3、公开接口头文件

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

添加对外公开的头文件

选择需要对外公开的.h(建议添加所有的.h,如果你只想对外提供部分的.h,要保证这些.h里面没有导入其他未添加到Copy Files的.h,否则你在编译后生成的.a在使用的时候就会报错)输入.h,然后command+a 全选,点击Add

快捷添加

4、设置适配所有架构

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

设置适配所有架构

5、运行工程进行打包

command + b 编译就会生成静态库了,

查看静态库
静态库目录

Debug-iphoneos 这个就是Debug模式的真机静态库,

可以通过选择Run的info设置 Debug 和 Release,设置Debug和Release。

通过选择Generic iOS Device 和 模拟器,设置真机和模拟器。

所以你会得到四种静态库:

Debug-iphoneos      Debug-iphonesimulator

Release-iphoneos      Release-iphonesimulator

Debug和Release设置

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

终端->cd进入库文件路径(Debug-iphoneos这个目录下面)->lipo -info 库名(lipo -info libSDWebImage.a)                         文件的路径:可以通过直接拖拽文件到终端

或者      终端->lipo -info .a的路径

查看静态库支持的架构

可以看到支持 armv7 arm64(静态库只要支持了armv7,就可以在armv7s的架构上运行)

如果不设置第4步:project -> buildSeting -> Build Active Architecture Only 设为NO,生成的静态库只会支持当前选择的模拟器或者真机的架构。

7.合并真机和模拟器的静态库

进入电脑的终端命令,进入到product的目录文件下,执行命令cd+product的文件路径

lipo -create 静态库1路径 静态库2路径 -output 合并的静态库名字(libSDWebImage.a)

lipo -info 静态库路径  查看静态库支持的架构,可以看到能够支持所有的架构了。

看了好多文章有说Debug和Release也能合并,但是没搞出来,有成功的麻烦也告知下我。


.frameworke文件静态库打包

1、依然Xcode创建一个新的工程FrameworkeLib,选择工程如下:(以打包MJRefresh为例)


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


然后把SDWebImage框架的所有文件拖拽到工程里面。


这里将MJRefresh.h删除了(不需要了),需要暴露的头文件写在MJRefreshFramework.h里面,以这样的形式#import


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

4、公开头文件

target-Build Phases - Headers -把需要公开的头文件从project拖入Public 或者右键Move to public Group(这里将全部头文件添加进去,根据需求添加想要暴露的.h,不要出现Public里的.h有import Project里的.h,被坑过)


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

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


6、选中真机(可以选择手机或者Generic iOS Device)或模拟器运行设备打包(与打包.a一样command + b),完成后Products文件夹下的MJRefreshFramework.framework文件由红色变成了黑色,右键show in finder


合并和查看静态库支持的架构和上面一样   

四、使用静态库 

使用的时候把合并的静态库拖拽到工程即可(如果有资源文件如bundle,还需要手动添加进去,系统不默认添加)

还有最近刚出xcode9试了下,好像编译打包在Products下面是没有静态库的,只好用xcode8了,还有如果用xcode9打开的项目,你在拖拽打包好的静态库到工程里面后Targets->select you target-->Build Phases->Link Binary With Libraries里面不会自动添加静态库,需要手动添加(很扯淡)



END

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容