iOS开发中的静态库与动态库

知识储备:

一.库(Library)

什么是库?

库是程序代码的集合,是程序共享代码的一种方式。根据源代码的公开情况,库可以分为开源库和闭源库。比如SDWebImage,AFNetworking,等可以看源码的叫开源库。闭源库,不公开源代码,是经过编译后的二进制文件,看不到具体的实现。闭源库又可以分为静态库和动态库。库说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。

二.静态库和动态库

和多数人所熟悉的动态语言和静态语言一样,这里的所谓静态和动态是相对编译期和运行期的

存在形式

静态库:.a 和 .framework    动态库: .dylib 和 .framework。 所以很多人误以为.a就是静态库,.framework就是动态库,不过系统的.framework都是动态库

静态库和动态库使用上的区别

静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝。编译完成后,库文件实际上就没有作用了,也这是它的优势。当然其缺点也很明显,就是会明显增大程序的体积。

动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,供多个程序调用,节省内存。由此可见动态库又可以叫共享库。注意:ios 8之前苹果禁止iOS开发中使用自己创建的动态库。原因估计是现在的iPhone,iPodTouch,iPad上面程序都是单进程的,也就是某一时刻只有一个进程在运行,那么你写个共享库,共享给谁呢?你使用的时候只有你一个应用程序存在,其他的应该被挂起了,即便是可以同时多个进程运行,别人能使用你的共享库里的东西吗?但是iOS8之后,出现了Extension,动态库有了用武之地,而且swift只支持动态库的使用,造成这个原因主要是swift的运行库没有被包含在iOS系统中,而是会被打包进App中(这也是造成Swift App体积大的原因),静态库会导致最终的目标程序中包含重复的运行库(这是苹果自家的解释)。

共同点:静态库和动态库都是闭源库,只能拿来满足某个功能的使用,不会暴露内部具体的代码信息,而从github上下载的第三方库大多是开源库

三.注意:

1.两种库都有framework的格式,但是它们长得一样吗?

iOS开发中的静态库与动态库_第1张图片
动态库framework
iOS开发中的静态库与动态库_第2张图片
静态库framework

2.当你创建一个framework文件时,系统“默认”是一个动态库的格式,如果想做成静态库,需要在buildSetting中将Mach-O Type选项设置为Static Library就行了!

iOS开发中的静态库与动态库_第3张图片
设置framework为静态库(默认动态库)

3. .a文件和.framework文件组成的区别:

.a文件是一个纯二进制文件,不能直接拿来使用,需要配合头文件、资源文件一起使用。

将静态库打包的时候,只能打包代码资源,但是图片文件、本地json文件和xib等资源文件无法打包进去,使用.a静态库的时候需要三个组成部分:.a文件+需要暴露的头文件+资源文件;

.framework文件内部除了有二进制文件(如下图黑色文件)之外还有其他的资源文件(相当于:.framwork文件=黑色二进制文件<.a文件+.h文件>+资源文件<图片、以及本地的html5,json,plist等),可以直接拿来在工程中使用

4.制作静态库时需要注意的几点:

(1)图片资源的处理:两种格式的静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。(.bundle文件很好弄,在桌面上新建一个文件夹,把它重命名为XXX.bundle就可以了(选中文件->右键->显示包内容->拖拽添加图片资源))。

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

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

四.实战制作库

iOS开发中的静态库与动态库_第4张图片
新建工程


iOS开发中的静态库与动态库_第5张图片
添加静态库并命名
iOS开发中的静态库与动态库_第6张图片
编码


iOS开发中的静态库与动态库_第7张图片
选择暴露的头文件(方法一)


iOS开发中的静态库与动态库_第8张图片
选择暴露的头文件(方法二  1)


iOS开发中的静态库与动态库_第9张图片
选择暴露的头文件(方法二 2)
iOS开发中的静态库与动态库_第10张图片
选择编译模式


iOS开发中的静态库与动态库_第11张图片
 设置Build active Architecture Only

注:Build active Architecture Only为什么设置为NO?

在目标设备上,执行设备对应的指令集。Build active Architecture Only 设置为YES,只会选择编译、链接对应的指令集,设置为NO时,会涵盖所有指令集,在必要的时候选择执行对应的指令集。所以一般在Debug时会选择设置为YES(效率会高点,虽然也没什么卵用),Release时会选择设置为NO,以支持所有可能的架构。

一般供人使用的库为release版本,这个版本apple会做一些优化。当Buld Active Archite Only为No时,会编译所有的版本arm7、armv7s、arm64。 各种指令集对应的手机为armv7:iPhone 3GS/4/4s  、armv7s:iPhone5 iPhone5c  、arm64:iPhone5s以上、 i386: mac(模拟器)。另外在命令行可以用命令$ lipo -info .../XXX.a 来查看库文件支持的指令集

将静态库分别选择在模拟器和真机设备中编译

iOS开发中的静态库与动态库_第12张图片
查看静态库


iOS开发中的静态库与动态库_第13张图片
真机 模拟器.a文件

从图中可以看到编译完后有两个文件夹,对应着真机和模拟器。接下来我们利用命令 lipo -create XXXX_1.a  XXXX_2.a -output XXXX_all.a,将真机和模拟器的库文件合并;(前面两个.a为真机模拟器路径;后面的为合并后想存放的路径并为合并后的命名,一般名字和之前的一样)


iOS开发中的静态库与动态库_第14张图片
使用静态库

将.a二进制文件和头文件放在一起,静态库就这样做完了。新建项目拉进去就可以直接使用了。可能大家有疑问为什么最开始的时候要新建一个project,并是在targets里添加静态库,当然你也可以直接按快捷键shift + command + N 来New一个Cocoa Touch Static Library,进行开发制作。但是这样无法测试你的静态库代码,无法打断点调试;如果你在你的工程里面添加静态库的话可以边开发边调试静态库的。

iOS开发Xcode7 Framework制作流程简介

静态库和动态库常见问题汇总

图片、界面xib等资源文件封装到.a静态库

你可能感兴趣的:(iOS开发中的静态库与动态库)