iOS 静态库和动态库的制作

静态库和动态库
一、静态库和动态库的存在形式

静态库: .a 和 .framework

动态库: .dylib 和 .framework

静态库和动态库在使用上的区别

静态库:链接时,静态库会被完整地复制到可执行文件中, 被多次使用就有多份冗余拷贝 (左图所示)

动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。

需要注意的是:项目中如果使用了自制的动态库,不能被上传到 AppStore!

静态库和动态库中之所以都有.framework,是因为苹果自己的framework是动态库,以供我们开发者使用,但是,我们自制时,制作的是.framework的静态库。

二、什么是.a、.bundle、.framework?

在iOS中静态库以.a和.framework的形式存在,动态库以.dylib和.framework的形式存在。

之所以.framework既可能是动态库又可能是静态库,是因为苹果公司禁止用户级App使用动态库,而自己却又堂而皇之的使用动态库,这就造成了iOS中系统级的.framework是动态库,用户级的.framework是静态库。

二者区别不大,.a是纯二进制文件,.a文件不能单独使用,至少要有.h文件配合,而.framework除了二进制文件外,还包含一些资源文件(头文件,plist等),由于自身包含了头文件,所以.framework可以单独使用。

.a和.framework两种静态库,通常都是把需要用的到图片或者xib文件存放在一个bundle文件中,而该bundle文件的名字和.a或.framework的名字相同。关于bundle文件的制作方法,后面第七大点介绍。

三、静态库使用的必要性

1>. 代码的共享与重用

2>. 程序模块化

3>. 分享给别人代码库时代码隐藏

4>. 开发第三方SDK

四、编译生成静态库时,模式:debug和release的区别

静态库分为真机—Debug(调试)版本、真机—Release(发布)版本、模拟器—Debug版本、模拟器—Release版本;开发中一般都打包Release(发布)版本,将真机和模拟器版本合并,提供外界。

DEBUG,好处在于Xcode开启很多服务来监控错误,让程序员来调试用,但是耗性能。RELEASE,好处在于则相反。
所以,建议:
——在生成静态库的时候,可以把上面Run的参数调整为Release,这样节省内存,运行速度快。
——在平时用Run调试的时候,在DEBUG下运作正常后,在发布程序之前可修改Run的参数为Release,再运行一下模拟发布的情况,因为有时候在Debug下正常,在Release下会崩溃,两者对错误的敏感度不同。

五、制作.a静态库

创建工程:

01.png

在Build Settings -->link ->Other Linker Flags中(xcode 8.2)工程自动添加了-ObjC。
在使用已经制作的静态库的工程中,若是静态库中有分类,也需要加上-ObjC。

接着需要做:在copy files中添加所有的.h文件,这些.h都是暴露在外面的:

02.png

先注意检查下面Release是否为NO:Yes表示只编译选中模拟器设备对应的架构,No则为编译所有模拟器设备支持的cup架构(Debug版本同理),选择NO,然后分别在模拟器和真机下Command+B编译一下,会看到Products文件夹下的.a文件变为黑色,这个.a文件就是我们想要得到的静态库:

01.png

(亲自测:release默认为NO,debug默认为YES。debug为YES情况下,在模拟器iphone6上编译,得到的库在7P上可以用,但是在5上就会崩溃,调整debug为NO,7和5都不崩溃)

合并模拟器的.a 和真机的.a(选Generic iOS Device 进行编译即可得到真机):
  1. 通过终端打开路径/Users/**/Library/Developer/Xcode/DerivedData/,选择对应的工程文件夹,就是进入制作静态库的工程。(在工程中的.a -- show in finder, 会看到Release-iphoneos和Release-iphonesimulator文件夹,分别是真机和模拟器的.a文件)
  2. 合并真机和模拟器.a文件,在终端输入以下命令行:lipo -create 模拟器.a文件的路径 真机.a文件的路径 -output 合并后的保存路径(例:lipo -create /Users/shelin/Library/Developer/Xcode/DerivedData/StaticLib/Build/Products/Release-iphoneos/libxxx.a /Users/shelin/Library/Developer/Xcode/DerivedData/StaticLib/Build/Products/Release-iphonesimulator/libxxx.a -output /Users/shelin/Desktop/StaticLib.a)最终会在桌面得到一个合并后的StaticLib.a文件,再将暴露出来的.h头文件一起复制出来。
    3.使用:只需将.a和暴露出来的.h头文件导入工程目录下就可供外界使用。
制作的另外一种方式:

不用创建一个新的工程,在源代码的项目里,新建一个target:


01.png
02.png

在和项目并列地方有TestAProduct文件夹,把需要编译成.a的文件拖入这个文件夹里面,添加TestAProduct需要暴露的头文件,选择TestAProduct目标工程运行,则在Products里面会有生成的.a库。(TestProduct的target里面的Compoile Sources需要有所有需要的.m的引用,不然运行不会生成,拖入之后,正常的target->TestPro也是可以运行的,因为它里面的Compoile Sources有.m的引用)


03.png
六、制作.framework静态库
  1. 创建.framework的静态和动态库都是:
002.png

静态和动态库的选择在于(linking-->Mach-o Type的选择):

001.png
  1. 创建工程后,这里的Headres是自携带的:
002.png

(把.h文件都放到public里面,不然会报找不到的错误)

01.png
02.png

编译生成真机和模拟器的framework静态库的方法和.a的方法是一样的,接下来就是合成真机和模拟器的库,这里和制作.a时的合并有点不同就是:
![Upload 0001.png failed. Please try again.]

这里合并用到的是里面的wgj_makeFramework:
![Upload 002.png failed. Please try again.]

例如:lipo -create /Users/wgj/Library/Developer/Xcode/DerivedData/wgj_makeFramework-gevmzbcgwfblmsewnayqsoutdztu/Build/Products/Debug-iphoneos/wgj_makeFramework.framework/wgj_makeFramework /Users/wgj/Library/Developer/Xcode/DerivedData/wgj_makeFramework-gevmzbcgwfblmsewnayqsoutdztu/Build/Products/Debug-iphonesimulator/wgj_makeFramework.framework/wgj_makeFramework -output /Users/wgj/Desktop/newFramework
其中,output后面的newFramework不是提前建好的文件夹,生成之前,桌面上不需要做操作。
这样,生成后,直接把桌面的生成的东东替换库里面的最后层次的wgj_makeFramework就好了,newFramework名字最好改为wgj_makeFramework。

七、制作.bundle

1、bundle资源库的特点

Bundle是静态的,也就是说,我们包含到包中的资源文件作为一个资源包是不参加项目编译的。也就意味着,bundle包中不能包含可执行的文件。它仅仅是作为资源,被解析成为特定的2进制数据

  1. 创建


    01.png

3、加入你需要编译在bundle中的资源文件(若是图片,需带后缀.png)。

当然,默认的配置也是可以的,如果你需要特定的优化或者特定的路径配置,你可以进行下面第4步的配置。

  1. 进行可选设置
    资源包只需要编译不需要安装:所以设置skip install 为YES;然后删除安装路径如下:


    02.png
  2. 编译即可得到.bundle文件
    6.导入项目应用,调用方式,例如图片的三种加载的方式:
    //1.
    // imageV.image = [UIImage imageNamed:@"wgj_bundle.bundle/Contents/Resources/0001.png"];
    //2.
    // NSString *fileS = [[NSBundle mainBundle] pathForResource:@"wgj_bundle.bundle/Contents/Resources/0001" ofType:@"png"];
    // imageV.image = [UIImage imageWithContentsOfFile:fileS];
    //3.
    NSString *path = [[NSBundle mainBundle] pathForResource:@"wgj_bundle" ofType:@"bundle"];
    NSBundle *bundle = [NSBundle bundleWithPath:path];
    NSString *file = [bundle pathForResource:@"0001" ofType:@"png"];
    imageV.image = [UIImage imageWithContentsOfFile:file];
    注意:在制作静态库时,若把静态库里面的图片(正常的图片,不是bundle里面的)暴露出来,则静态库工程和用到静态库的工程可以直接用,[UIImage imageNamed:@"has.png"];如果是不暴露出来,则静态库工程和用到静态库的工程都用不了(静态库工程用了无效)。若是在制作静态库的时候,用.bundle文件封装图片资源,静态库制作时,把.bundle文件暴露在外界,则也是一种方法,在外界通过路径加载也是可以使用到图片的(.bundle文件不暴露在外界,图片在静态库中,也是使用无效的)
    (资源文件都打包放在这里。在制作Framework的时候不可以把图片直接放在项目中,否则制作好之后图片是一张一张的出现在项目中非常乱,需要新建一个bundle将图片放进去,这里的bundle提供整个SDK的图片资源。
    注意:图片放进bundle之后不可以用[UIImage ImageWithName:]读取图片。要先找到bundle包再拿图片)
八、制作.framework动态库

制作.framework的动态库和制作.framework的静态库基本相同,其不同点:

01.png

制作库时这个地方改为:Dynamic Library,另外在使用已制作动态库的 工程中添加:

02.png

这个图片中的Embedded Binaries 里面的库是自制的动态库,需要手动添加。
当然在使用静态库时,需要把这个Embedded Binaries 中的已手动添加的动态库去掉。(在导入自己制作的动态库时,需要在Embedded Binaries中导入,不然会报错:image not found。此时这个动态库会跟静态库一样被拷贝到目标程序中进行编译,苹果又把这种Framework叫做Embedded Framework)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容