我们经常听说静态库和动态库,但是没有自己真正去实现过这两种库。本文就如何实现做个备注:
静态库:.a和.framework
动态库:.tbd和.framework
静态库和动态库的区别
.a文件肯定是静态库,. tbd肯定是动态库,.framework可能是静态库也可能是动态库
静态库在链接时,会被完整的复制到可执行文件中,如果多个App都使用了同一个静态库,那么每个App都会拷贝一份,缺点是浪费内存。类似于定义一个基本变量,使用该基本变量是是新复制了一份数据,而不是原来定义的;
动态库不会复制,只有一份,程序运行时动态加载到内存中,系统只会加载一次,多个程序共用一份,节约了内存。类似于使用变量的内存地址一样,使用的是同一个变量;
在iOS8.0以后苹果开放了动态加载. tbd的接口,用于挂载. tbd动态库,项目中也可以使用了自己定义的动态库。
.a静态库是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用(内部直接包含了要展示方法的.h文件)。
使用静态库的好处
模块化,分工合作
避免少量改动经常导致大量的重复编译连接
也可以重用,注意不是共享使用
使用动态库的好处
使用动态库,可以将最终可执行文件体积缩小
使用动态库,多个应用程序共享内存中得同一份库文件,节省资源
使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。
静态库的使用场景
保护自己的核心代码,自己不想别人看到的部分
将MRC的项目打包成静态库,可以在ARC下直接使用,不需要在转换
iOS设备的CPU架构
模拟器
4S-5:i386
5s-7P:x86_64
真机
armv6:iPhone - iPhone3G
armv7:iPhone 3Gs,4,4S,iPad,iPad2
armv7s: iPhone 5、iPhone 5c <静态库只要支持了armv7,就可以在armv7s的架构上运行>
arm64:iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3
没有armv64
.a静态库
1.创建一个新的工程,选择下面这个模板:
a1.jpeg
完成
a2.jpeg2.我这里就在Test操作了(亲,你打包.a的时候,可以删除默认文件,拉入自己想加入的任何文件)
a3.jpega4.jpeg
下面在创建一个Person类
a5.jpeg a6.jpeg
3.选择需要公开的头文件
-
添加头文件
a7.gif
4.修改配置
-
a8.jpegBuild Active Architecture Only
修改为NO,否则生成的静态库就只支持当前选择设备的架构。
-
a9.jpegiOS Deployment Target
,静态库需要支持版本
-
a10.jpegach-O Type
更改成Static Library
,.a默认就是Static Library
,这一步可以省略
5.编译
选择Generic iOS Device
和任意一个模拟器
各编译一次,完成后,在工程的Products文件夹下的.a文件从红色编程了黑色。编译成功,然后Show in Finder
。
a11.gif
可以看到真机与模拟器都生成了.a。里面都有有我选择公开的头文件
这个时候,可以用命令lipo -info
静态库名字来看下,支持的iOS的CPU框架
a12.gif -
Debug-iphoneos里面支持armv7、arm64,属于真机,用到模拟器就会报错
-
Debug-iphonesimulator里面支持i386、x86_64,属于模拟器,用到真机会报错
6.合并静态库-让模拟器和真机使用一个静态库
命令如下:
lipo -create 第一个.a文件的绝对路径 第二个.a文件的绝对路径 -output 最终的.a文件路径
tip
:
路径下面要手动填写文件/xxx..a
这个生成的
libTest.a
,就是支持真机和模拟器的静态库了。创建一个文件夹,把.a和头文件拖进去,这个文件夹就是我们所需要的。done.gif
为了开发方便,我们可以使用生成的通用静态库,但是上线的时候只导入真机的,这样工程的体积也会小一些。
使用.a静态库
新建一个工程,把我们的静态库拖进去,导入头文件。同时也要把头文件手动导进去!!!!!
last.jpeg
.framework静态库
1.Xcode创建一个新工程,需要选择这个Cocoa Touch Framework
这个模板
创建完成后的framework.h
和Infn.plist
不要删除(创建framework的时候命名不要用framework命名,否则在使用这个framework的时候会报错)
2.创建Person,也是输入名字和年龄,和.a一样
frame2.jpeg
frame3.jpeg
创建好的文件,要在自动生成的头文件中导入!!!!!
注意事项:
- 如果打包的文件中有设置图片的地方,如果还是通过[UIImage imageNamed:]的方式设置,图片可能不会显示。
- 图片最好单独打包一个bundle,这个时候设置图片的方式为:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//拿到路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle" ofType:@"bundle"];
//设置图片
UIImage *image = [UIImage imageNamed:@"delete" inBundle:[NSBundle bundleWithPath:path] compatibleWithTraitCollection:nil];
[button setImage:image forState:UIControlStateNormal];
3.选择要公开的头文件
这里主要是让使用者知道有哪些方法和头文件可以使用
-
第一种添加头文件的方式,把需要公开的头文件添加到public里面
frame4.jpeg -
第二种添加头文件的方式。在右侧的选择中,选择Public
frame5.gif
注意。要在这个文件中引入需要公开的头文件
frame6.jpeg
这里有一个注意点,公开的头文件中,#import的其他类也要公开,添加到public中,如果不想公开,就在头文件用用@class的方式,在对应的.m中用#import方式
4.修改配置
-
Build Active Architecture Only
修改为NO,否则生成的静态库就只支持当前选择设备的架构。
frame7.jpeg -
Mach-O
格式,因为动态库也可以是以framework形式存在,所以需要设置,否则默认打出来的是动态库。
静态库Static Library
(默认为Dynamic Library)
frame8.jpeg -
支持版本
frame9.jpeg
5.编译
选择Generic iOS Device
和任意一个模拟器各编译一次,完成后,在工程的Products文件夹下的.a文件从红色编程了黑色。编译成功,然后Show in Finder
。
可以看到真机与模拟器都生成了.framework。里面都有我们选择公开的头文件
这个时候,可以用命令
lipo -info framework
静态库文件下二进制文件的名字来看下,支持的iOS的CPU框架frame11.gif
- Debug-iphoneos里面支持armv7、arm64,属于真机,用到模拟器就会报错
- Debug-iphonesimulator里面支持i386、x86_64,属于模拟器,用到真机会报错
6.合并静态库-让模拟器和真机使用一个静态库
命令如下:
lipo -create 第一个framework文件下二进制文件的绝对路径 第二个framework文件下二进制文件的绝对路径 -output 最终的二进制文件路径/xxx.framework
tip
:
路径下面要手动填写文件/xxx(二进制文件名字,无后缀哦!)
将合成的二进制文件拖进任何一个framework,替换掉原来的,然后把这个新的framework拖进项目就可以使用了
使用framework静态库
新建一个工程,把我们的静态库拖进去,导入头文件。然后调用Person中的方法。
frame12.jpeg
如果静态库中有Category类,就要在使用静态库项目的配置中添加-ObjC
或者-all_load
如果创建的framework类中使用了.tbd
,则项目中也要导入.tbd
动态库。
以上内容系转载!自己不懂的地方做了部分修改。
网友评论