引言
在开发中.framework静态库还是比较常见的,我们可以把一些不愿意让别人见到的代码,用静态库的方式把它隐藏起来,只留下.h文件显示方法供编程人员使用。而.a文件出了静态库本身外,还需要引入.h文件,而.framework就不需要如此,由于.framework的方便性所以一般情况下我们见到的较多。
库
库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。
静态库:以.a
和 .framework
为文件后缀名。
动态库:以.tbd
(之前叫.dylib
) 和 .framework
为文件后缀名。
静态库与动态库的区别
静态库和动态库是相对编译期和运行期的:
动态库:运行时获取
静态库:只读一次,编译时获取
//注意:苹果禁止一切未开源的代码在APP中使用,也就是说上传APP的时候,要将代码告知给苹果,审核通过之后才能上传使用,若苹果发现上传的APP中包含静态库或者动态库则会拒绝上架。
001-静态库.a 创建
1.新建工程
比如我们的工程名叫HKLibTest,那么我们创建的.a 静态库最好就是前面加个Lib,如:LibHKLibTest.a
新建工程 (选中xcode,按commond + shift + N)
此时工程目录是这个样子,.a文件还没有被创建,因此是红色的
你可以把图中 HKLibTest.h
和.m
换成你自己要生成库的文件(可以是多个),在这里我就不换了,就用这两个文件,我们在.h
文件中添加一个方法+sayHello
,并在.m
中实现它
#import "HKLibTest.h" @implementation HKLibTest + (void)sayHello { NSLog(@".a静态库:Hello, World ~"); } @end
2.添加Headers
按照下图顺序进行操作
Build Phases ->添加 -> New Run Script Phase
选中所有的.h文件,在点击Add
/* 这里需要注意的是暴露出来的头文件中import的其他类也得添加到public中暴露出来。 如果不想将import的类暴露出来,那么在头文件中用@class 然后在对应的.m文件中再import。 总之 1. 你再外面用到的类,一定要暴露出来; 2. 你暴露出来的类,头文件中导入的类也一定是暴露出来的 3. 如果提示导入头文件报错,找不到文件,找不到谁暴露谁就对了 */
3. 进行打包前的一些配置
设置编译模式,打开xcode菜单Product -> Scheme -> Edit Scheme,改成release模式,如下图
编译机器的选择,如下图,一定要选择NO。(如果选择yes,生成部分机型,选择NO则适配所有机型)
4. 接下来,我们进行打包
操作简述: Command + B
1. 在真机情况下编译 (Generic iOS Device),并记录下.a
文件的绝对路径
2. 在模拟机情况下编译(随便吧,我用的是iPhone8Plus),并记录下.a
文件绝对路径
3. 用命令行合并1、2部记录的文件,到新的.a
文件,名字最好取开始我们取的名字吧,命令行:lipo -create 真机静态库路径空格模拟器静态库路径 -output 最终文件路径(桌面)
4. 把你要暴露的.h
文件和你已经生成的.a
文件搞到一个文件夹里,这个文件夹就可以直接拖到工程里用啦
//真机静态库路径 /Users/MengYu/Library/Developer/Xcode/DerivedData/HKLibTest-cqiexexehimllgdmfaxigfagpzet/Build/Products/Release-iphoneos/libHKLibTest.a //模拟器静态库路径 /Users/MengYu/Library/Developer/Xcode/DerivedData/HKLibTest-cqiexexehimllgdmfaxigfagpzet/Build/Products/Release-iphonesimulator/libHKLibTest.a
合成:
//$lipo -create /Users/MengYu/Desktop/真机静态库/libHKLibTest.a /Users/MengYu/Desktop/模拟器静态库/libHKLibTest.a -output /Users/MengYu/Desktop/LibHKLibTest.a
在桌面就可以看到合成之后的.a文件了
把我们刚合成的.a文件和想暴露的.h文件,弄到一个文件夹下
静态库创建完成~
导入HKDemo工程中:
#import "ViewController.h" #import "HKLibTest.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [HKLibTest sayHello]; }
补充:
/* 1.category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC。 2.如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。 */
002-静态库.Framework创建
1.新建工程
比如我