Overview
- 库是程序代码的集合,是共享程序代码的一种方式
- 根据源代码的公开情况,库可以分为2种类型开源库和闭源库。
- 开源库公开源代码,能看到具体实现,比如Masonry、AFNetworking、SDWebImage等(GitHub是个开源库平台)。
- 不公开源代码,是经过编译后的二进制文件,看不到具体实现
主要分为:静态库、动态库。
使用情况
闭源库
- 国内的企业,掌握有核心技术,同时是又希望更多的程序员来使用其技术,因此采用"闭源"的方式开发使用。例如:百度地图,友盟,JPush等
- 在企业开发中,一些核心技术或者常用框架,出于安全性和稳定性的考虑,也会提供静态库给程序员使用。
- 基本思路
- 将自己的核心代码编译成静态库(视频软件核心是对视屏流的解码)。
- 对外暴露统一的接口。
- 开发者集成闭源库,并且调用API使用。
开源库
国内使用最多的应该是GitHub平台来分享开源库。
- 技术共享:程序员可以通过公开源码分享技术
- 能力共建:程序员可以共同出力开发更优秀的作品
静态库和动态库介绍
库形式
- 静态库:.a和.framework
- 动态库:.framework和.dylib和.tdb
Xcode7 之后.dylib改名为.tdb,原因:For those who are curious, the .tbd files are new "text-based stub libraries", that provide a much more compact version of the stub libraries for use in the SDK, and help to significantly reduce its download size.
简单翻译:给好奇者的的解释:.tbd 文件是新的“基于文本的存根库”,它是根存库的一个非常小的版本,能显著降低app的大小。请参考stackoverflow分析
使用区别
- 静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝。
- 链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存
- 项目中如果使用了自制的动态库,不能被上传到AppStore。
这里插入一句静态库的使用细节(英语都比较简单,看配图)
- Link binary with libraries Link frameworks and libraries with your project’s object files to produce a binary file. You can link a target’s source files against libraries in the target’s active SDK or against external libraries.
- Embed Frameworks You can create an embedded framework to share code between your app extension(APP扩展) and its containing app.
- If your containing app target links to an embedded framework, it must include the arm64 architecture or it will be rejected by the App Store.// stackoverflow分析
静态库和CPU架构
- 设备的CPU架构
- 不同的设备使用的CPU是不同的
- CPU的不同造成使用的CPU架构(指令集)不同
- 静态库有其支持的CPU架构
- 如果静态库在不支持的CPU架构上运行就会报错
- 模拟器使用的CPU架构
- iPhone4s-iPhone5 : i386
- iPhone5s-iPhone7 : x86_64
- 真机使用的CPU架构
- iPhone3gs-iPhone4s : armv7
- iPhone5-iPhone5c : armv7s
- iPhone5s-iPhone7 : arm64
- 唯一特殊:只要支持armv7的静态库可以在armv7s上正常运行
编译闭源库
注意:虽然从Xcode5开始用到系统自带的框架不用导入框架, 但是如果是在静态库中用到了这些框架还是必须导入-ObjC这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大(因为加载了其他的objc代码进来)。但是如果静态库中有类和category的话只有加入这个flag才行。-all_load这个flag是专门处理-ObjC的一个bug的。用了-ObjC以后,如果类库中只有category没有类的时候这些category还是加载不进来。变通方法就是加入-all_load或者-force-load。-all_load会强制链接器把目标文件都加载进来,即使没有objc代码。-force_load在xcode3.2后可用。但是-force_load后面必须跟一个只想静态库的路径。
lipo的使用
简介
lipo源于mac系统要制作兼容powerpc平台和intel平台的程序。
lipo 是一个在 Mac OS X 中处理通用程序(Universal Binaries)的工具。
静态库使用
-
查看静态库信息
lipo -info 文件名
-
合并静态库(一般是模拟器和真机的合并)
lipo -create 静态库存放路径1 静态库存放路径2 ... -output 整合后存放的路径
-
拆分静态库
lipo 静态库源文件路径 -thin CPU架构名称 -output 拆分后文件存放路径 例如:lipo libname.a -thin armv7 -output libname-armv7.a
Tip:framework(静态库)的路径在framework包的下一层。支持同一架构的库不能合并。
创建库项目
iOS 8.0起,Apple为了更充分地发挥GPU的潜力,引入了Metal框架。Metal是与OpenGL ES是并列的,它们都是应用对GPU访问的底层接口。而Metal则提供了更底层,更面向硬件的接口,这也是为何Apple给这个框架起名为“Metal”的原因。Metal参考
从图上我们可以看到Xcode三种库形式,从Xcode6开始提供了Framework的创建入口。这里一定要记清他们的图标,方便自己的认知。也要记得App Target 的图标是A(艺术A)。
接下来具体的创建使用请参考
使用注意点
- Mach-O文件选择
这个就是可执行文件的类型(或者说是编译之后的核心文件类型)有兴趣的可以参考:Mach-O 可执行文件 、Bitcode的工作流程及安全性评估、Bitcode适配指南
我们在创建.a库的时候Mach-O文件默认是Static Library;而我们创建.frameword库之后,Mach-O文件默认是Dynamic Library;
- Architecture架构选择
这里选择真机的时候一样。
- 库的类型除了动态库和静态库之外,对于开发者来说,还有release版本和debug版本之分。
刚才也说过,同一架构的库不能合并,也就是release版本和debug版本的库不能合并。