库 就是程序代码的集合, 是共享程序代码的一种方式
- 开源库
- 公开源代码, 能看到具体实现
- 例如MJExtension, MJRefresh, AFNetworking...
- 闭源库
- 不公开源代码, 是经过编译后的二进制文件, 看不到具体实现
- 主要分为: 静态库 和 动态库
.a
.framework
.dylib
.framework
- 静态库在链接时, 会被完整的复制到可执行文件中; 被多次使用, 就有多份拷贝;
- 动态库则不会复制, 只有一份. 程序运行时动态加载到内存; 系统只加载一次, 多个程序共用, 节省内存;
- 但是!!!! 项目中如果使用到自己的动态库, 不允许上架!
- 再但是!!! WWDC2014上公布的 苹果对ios8开放动态加载dylib的接口 也就是说 开放了动态库挂载
- 保护自己的核心代码
- 国内的企业,掌握有核心技术,同时是又希望更多的程序员来使用其技术,因此采用"闭源"的方式开发使用
- 例如:百度地图,友盟,JPush等
- 将MRC的项目,打包成静态库, 可以在ARC下直接使用, 不需要转换
.a
+.h
- 看不到具体实现的代码
- 创建项目时, 直接选择静态库(.a)
- 设置需要暴漏的头文件
TARGETS
→Build Phases
→Copy Files
→ 把需要暴漏的头文件添加进来即可
- 在模拟器环境下编译(得到模拟器环境下的静态库)
- 选择模拟器6S,编译
- 在真机环境下编译(得到真机环境下的静态库)
- 使用6S模拟器进行测试, 通过
- 使用真机, 编译; 失败
- 使用低型号模拟器测试,; 失败
- 模拟器下的静态库和真机下的静态库不能共用
- (各个模拟器型号之间架构也不一样)
- 主要原因是模拟器和真机CPU架构不一样
-
不同机型的CPU, 对应的架构不同;
-
模拟器:
机型 架构 4s - 5 i386 5s - 6s Plus x86_64 -
真机:
机型 架构 3gs - 4s armv7 5/5c armv7s(armv7兼容armv7s) 5s - 6s Plus arm64 -
查看静态库支持的架构
lipo -info 库文件
- 分别选中不同的模拟器, 进行编译, 查看不同的静态库支持架构
-
怎样一次编译支持多个架构的的静态库?
- 问题描述:
- 正常情况下, 需要选中每一个模拟器进行编译, 生成支持对应架构的静态库. 然后合并; 非常蛋疼
- 解决方案:
Build Settings
→Build Active
→NO
- 表示不止编译活跃的架构, 让所有的架构都编译
- 问题描述:
- 真机-Debug版本
- 模拟器-Debug版本
- 特点
- 调试版本会包含完整的符号信息,以方便调试
- 调试版本不会对代码进行优化
- 真机-Release版本
- 模拟器-Release版本
- 特点
- 发布版本不会包含完整的符号信息
- 发布版本的执行代码是进行过优化的
- 发布版本的大小会比调试版本的略小
- 在执行速度方面,发布版本会更快些,但不意味着会有显著的提升
项目 → Edit Scheme
→ Run
→ Release/Debug
分别进行编译
- 因为静态库针对于模拟器和真机生成了不同版本(支持不同架构), 所以没法同时运行
- 解决方案(静态库的合并):
-
检测
.a
的类型lipo -info libCZTools.a
-
合并
.a
lipo -create Debug-iphoneos/libTools.a Debug-iphonesimulator/libTools.a -output libTools.a
-
特点
- 合并
.a
的好处,开发过程中既可以在真机上调试,也可以在模拟器上调试 - 合并
.a
的坏处,如果静态库太大,合并打包后,会非常大,因此很多第三方的静态库的 .a
是区分版本的 - 今后在使用
.a
时一定注意版本
- 合并
-
补充: 拆解指定架构的库
lipo -thin 架构名称 架构路径 -output 目标路径
-
-
新建工程, 直接选择.framework静态库
-
编译时, 设置编译所有架构
-
默认制作的是动态库, 需要设置链接类型
target
→Build Settings
→ 搜索Mach-o Type
→ 改为静态库
-
确定是静态库
-
确定支持模拟器或者真机中的所有架构
Build Settings
→Build Active
→NO
- 表示不止编译活跃的架构, 让所有的架构都编译
-
提供的静态库应该是
release
版本- 项目 →
Edit Scheme
→Run
→Release/Debug
分别进行编译
- 项目 →
.a
是一个纯二进制文件,.framework
中除了有二进制文件之外还有资源文件.a
文件不能直接使用, 至少要有.h
文件的配合,.framework
文件可以直接使用.a
+.h
+sourceFile
=.framework
- 建议使用
.framework
- 由于 Xcode 默认在编译时会把所有的素材文件导入到 mainBundle 中,可能与使用静态库的程序冲突。
- 解决方案:
- 在静态库中如果要使用图片素材,会利用 bundle 的手段
- 建立 bundle,并且向其中添加图片
- 创建一个类方法,返回图片
- 编译
- 调用方如果需要使用,需要导入
.h
+ .a
+XXX.bundle
- 在静态库中如果要使用图片素材,会利用 bundle 的手段
建议使用一个主头文件包含其他头文件, 让用户只导入一个主头文件
- 静态库本身就是一个小项目, 实现某些功能, 但是这些功能在开发中也需要测试. 而测试代码又不能作为静态库的一部分
- 解决方案:
- 创建复合项目
lipo -create xx xx -output xxx
lipo -thin 架构名称 xx -output xx
lipo -remote 架构名称 xx -output xx