1、什么是库?
库(Library)就是编译好的二进制代码,加上头文件就可以对外提供使用.
封装库的原因:
1)代码提供给外部使用,但是不希望被看到源码,这种情况就需要封装成库,对外只暴露头文件。
2)对于不会进行经常改动的代码,比如某些模块,可以编译成库,既节省编译时间,也便于代码的管理。
因为库是编译好的二进制文件,工程中编译的时候需要link加入的库,link有不同的形式,分为静态和动态,分别对应于静态库和动态库。
2、什么是静态库
一般ios工程中使用到的第三方SDK基本上都是静态库。
静态库的特点:
1)在App工程编译的时候静态库文件会被拷贝一份编译到目标程序中,相当把静态库嵌入到App中了,生成的App二进制文件的体积也因此会变大。
2)使用时,需要手动导入静态库依赖的其他库。(例如我们制作的zzzzzz.a库使用到了CFNetwork.framework,那么zzzzzz.a被使用时需要手动导入,有时候需要link到n多个系统库,我们只能耐心添加)
3)如果导入的是第三方动态库,如果找不到的话App会报崩溃,在使用xCode编译工程的时候经常会出现**lib not found。
4)静态库可以减少耦合性,因为静态库是不能包含其他静态库的,制作的静态库被使用时是需要导入它的依赖库的,从而保证了每个静态库的独立性,避免重复引用。
在link静态库的时候涉及到几个概念
TARGET --> Build Phases见下图
1、Target Dependencies(目标依赖):对工程文件编译之前先对依赖目标进行编译。也就是说Target Dependencies仅仅是对目标进行编译,而不是把目标(指其他工程)和工程文件连接起来。
2、Link Binary With Libraries:把当前工程和库文件关联起来生成二进制文件,也就是说这一步是关联当前工程文件和库文件。
注意事项
注意在我们制作静态库的时候,可能会遇见通过命令:lipo -info xxx.a查看生成的库文件只支持x86_64 arm64 的情况,正常情况是需要支持至少i386、armv7、x86_64、 arm64这4中的,原因是如下图1的IOS Deployment Target没有指定最低版本,目前(2018.7.4)最低是8.0,然后需要设置Base SDK 为最最高版本,目前是11.4,这样就能覆真机和模拟器的所有版本了。调整后再编译打包,然后使用命令行合并真机和模拟器的库文件
下面是用到的命令行:
1、查看项目库文件支持的架构
lipo -info xxxx.a
可能输出:i386 armv7 x86_64 arm64 或者其中的部分
2、合成真机和模拟器的库文件
lipo -create [自己机器上的项目目录]/Products/Debug-iphoneos/xxxx.a [自己机器上的项目目录]Products/Debug-iphonesimulator/xxxx.a -output [自己机器上的项目目录]/Products/xxxx.a3、将文件拷贝到桌面
cp -R xxxx.a /Users/xxx/Desktop (注意在这个命令是在xxxx.a文件所在目录进行的)
图1:
图2:
遇到的问题
1)当制作的xxxx.a 静态库包含其他第三方.framework静态库时,在使用xxxx.a静态库的时候报找不到其包含的.framwork库
2)在制作的静态库中如果包含了其他第三方的静态库,比如我需要制作一个login.a的静态库,里面需要包含facebook登录,那么我需要先去facebook开发者网站下载相关的sdk包括:Bolts.framework、 FBSDKCoreKit.framework、 FBSDKLoginKit.framework这三个静态库,但是在使用xxxx.a文件的时候,发现这几个库都找不到了,
解决办法
把三个库同时加入到使用xxxx.a的工程中就解决了
原因
framework的第三方库,只是参与link,并不会 build 进自作的 xxxx.a的binary,所以项目必须同时引用xxxx.a 和它引用的所有xxxx.framework库文件