静态库与动态库的制作与使用
什么是库?
库是共享程序代码的方式,一般分为静态库和动态库。
静态库
链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。
动态库
链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。
iOS里静态库形式?
.a形式 和 Framework
动态库形式
.dylib和.framework
为什么Framework既是静态库又是动态库
系统的.framework是动态库,我们自己建立的.framework是静态库。
.a与.framework有什么区别
- .a是一个纯二进制文件
- .framework中除了有二进制文件之外还有资源文件
- .a文件不能直接使用,至少要有.h文件配合
- .framework文件可以直接使用
- .a + .h + sourceFile = .framework
- 建议用.framework
为什么要使用静态库?
- 方便共享代码,便于合理使用。
- 实现iOS程序的模块化。可以把固定的业务模块化成静态库。
- 和别人分享你的代码库,但不想让别人看到你代码的实现。
制作静态库时的几点注意:
- 注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件+.h+其它资源文件的形式,不同的是,.a本身就是二进制文件,需要我们自己配上.h和其它文件才能使用,而.framework本身已经包含了.h和其它文件,可以直接使用。
- 图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。
- category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-objc。
- 如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。
让我们制作一个.a的静态库先熟悉一下
1. 创建一个工程(选择第二个静态库)
2.创建出来是这样的
3.现在随便输点东西,比如写一个方法在.h里,然后在.m里写一个NSLog就行
4.直接跑起来,先用模拟器跑,再用iOS Device跑
这时,product里面的东西就变黑色了,然后点show in finder
5.很明显一个模拟器的,一个真机的,因为模拟器和真机架构不一样(我是这么理解的),那个libuniversal.a是我后面生成的一个合并通用的,一会说。
完了,然后直接导入你的测试工程,import就行了,用引号””
记得导入的时候导入模拟器的那个.a 和include文件夹里的.h
静态库有关的终端命令
cd 改变文件夹
pwd 显示当前路径
ls 显示当前文件夹中的所有文件的子文件夹
lipo -info [文件名称] :显示静态库文件的架构类型
iphone用lipo合并模拟器库和真机库,发布一个通用的静态库
lipo -create [文件名称1,文件名称2,…….,文件名称n] -output [生成的文件名称]
如:把包含模拟器架构的静态库和包含iPhone真机的架构的静态库合并为一个通用的静态库
lips -create libiPhone模拟器.a libiPhoneOS.a -output libiPhone通用.a
//静态库中是不能包含资源文件的!!!(图片,xib,音频等)
需要资源文件的时候,生成file.bundle。
bundle直接重命名文件夹加后缀就行了
获得bundle中的资源
VC获得bundle中的资源
NSString * bundlePath = [[ NSBundle mainBundle] pathForResource: @ "MyBundle" ofType :@ "bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithPath:bundlePath];
UIViewController *vc = [[UIViewController alloc] initWithNibName:@"vc_name" bundle:resourceBundle];
图片获得bundle中的资源
UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
UIImage *image = [UIImage imageNamed:@"MyBundle.bundle/img_collect_success"];
[imgView setImage:image];
制作一个framework
我发现网上有很多创建Framework 的教程,什么乱七八糟用的版本就不知道什么版本的,好吧,其实是我看不懂
也没多难,还是第一个图片,创建一个framework的项目
什么也没有 ,就一个.h文件(这东西真不知道有什么用,不过Google上的大神说有用,还是别删了)
然后自己创建个类呀什么的,放点图片呀什么的都行,我就懒了,不写那么多了