码迷,mamicode.com
首页 > 移动开发 > 详细

iOS 最新framework和.a静态库制作及使用全解

时间:2016-05-15 10:51:31      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

  最近想把自己的一些实用工具类搞成一个静态库,网上搜了下关于framework和.a的一些相关资料,然而写的或不全面,或不详细,我归纳总结及亲自实践写下这篇文章。由于篇幅原因多工程联调见另一个博客iOS 工程套子工程,主工程和framework工程或.a静态库工程联调

一、framework和.a两种静态库的介绍及区别

.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。

.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。

.a + .h + sourceFile = .framework。

.a只是静态库。framework既可以是静态库也可以是动态库。例如系统的framework就是动态库。

静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。

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

然而苹果是不会让开发者有自己的动态库的。

二、framework制作及使用

1.新建framework项目

技术分享

2.加一些我们实用的类进来

3.文件刚拉进来时如下图,只有APPBaseSDK.h是默认放在public中,我们还要把project中需要暴露给外面用的.h文件移到public中去

技术分享

4.然后设置编译模式,打开Xcode菜单Product--->Scheme--->Edit Scheme,改为release模式,因为最终打包是要用release模式

技术分享

5.设置最低支持版本

技术分享

6.设置编译出的静态库包含的指令集

技术分享

模拟器:iPhone4s~5 : i386 iPhone5s~6plus : x86_64
真机:iPhone3gs~4s : armv7 iPhone5~5c : armv7s iPhone5s~6plus : arm64
如果Build Active Architecture Only设置为YES,那么编译出来的静态库就只包含当前设备的指令集。
举个例子:如果我们选择iPhone 5模拟器编译,则编译出来的静态库只能用iPhone4s~5模拟器跑程序,用iPhone5s~6plus,则会报找不到x86_64的APPBaseSDK库。
设置为NO,则会把所有指令集的都打包合并。因此静态库有个缺点就是静态库包比源码大很多。

7.最后修改生成的Mach-O格式

技术分享

8.编译生成静态库

编译时,需要用模拟器和真机各编译一次,这样Products目录下的APPBaseSDK.framework静态库才会变为黑色,右键show in Finder,可以进入Products目录下。

技术分享

9.合并静态库文件

要让真机和模拟器都可用该静态库,需要将两种静态库合并。framework静态库合并的不是framework,而是framework下的一个二进制文件,即上图中标记的待合并文件。lipo -create 第一个framework下二进制文件的绝对路径 第二个framework下二进制文件的绝对路径 -output 最终生成合并的二进制文件路径(我把它放桌面上)。
打开终端使用的命令如下:

lipo -create /Users/zhanglinfeng/Library/Developer/Xcode/DerivedData/APPBaseSDK-dpqdspcdgwsrxgdihiaxpqpkvali/Build/Products/Release-iphoneos/APPBaseSDK.framework/APPBaseSDK /Users/zhanglinfeng/Library/Developer/Xcode/DerivedData/APPBaseSDK-dpqdspcdgwsrxgdihiaxpqpkvali/Build/Products/Release-iphonesimulator/APPBaseSDK.framework/APPBaseSDK -output /Users/zhanglinfeng/Desktop/APPBaseSDK

如果觉得敲文件路径好麻烦,可以将该文件拖入终端即键入了该文件的路径。如果报错建议将上图中Release-iphoneos和Release-iphonesimulator中的APPBaseSDK.framework删掉,重新用模拟器和真机分别编译一次再试。

真机的或者模拟器中随便选一个framework,将该framework中的二进制文件APPBaseSDK(也就是上图中待合并的文件)替换成刚刚合并的文件(刚生成在桌面上的)。好了,此framework就是我们需要的。

10.使用framework

将framework拖入新建的一个UseFrameworkTest工程,我这里拖到下图箭头所指的UseFrameworkTest文件夹目录下,如果你要拖到其他目录,就要改Framework Search Paths,后面我会介绍Search Paths路径相关知识

技术分享

将framework中比较常用的头文件import到APPBaseSDK.h中(如下图画圈的),这样在外面只需要#import <APPBaseSDK/APPBaseSDK.h>,就可以引用到下图中画圈的文件。如果不想将太多文件都import到APPBaseSDK.h中,在外面就像这样引用#import <APPBaseSDK/MBProgressHUD+Easy.h>(虽然能使用但会报警告,所以还是import到APPBaseSDK.h中吧)

技术分享

使用代码,如下图可以正常调用将汉字转拼音方法并打印结果了

技术分享

注意:如果要用到framework中的category方法,需要设置Other Linker Flags为-ObjC(注意大小写,有些资料里大小写搞错了坑死我了)。引入了-ObjC标志,它的作用就是将静态库中所有的和对象相关的文件都加载进来本来这样就可以解决问题了,不过在64位的Mac系统或者iOS系统下,链接器有一个 bug,会导致只包含有类别的静态库无法使用-ObjC标志来加载文件。变通方法是使用-all_load 或者-force_load标志,它们的作用都是加载静态库中所有文件,不过all_load作用于所有的库,而-force_load后面必须要指定具 体的文件。

 三、.a静态库的制作及使用

1.创建静态库工程,工程命名为BaseSDK,生成的.a文件名变成libBaseSDK。

技术分享

2.删掉自动生成的文件BaseSDK.h   BaseSDK.m

技术分享

3.添加你的实用类文件

技术分享

4.添加Headers Phase

技术分享

5.将暴露给外面用的头文件加入进来,加进来后要移到public中去(不移到public中也没错,只是下面第11步中不会出现.h文件,需要从库的源码中找)

技术分享

6.然后设置编译模式,打开Xcode菜单Product--->Scheme--->Edit Scheme,改为release模式,因为最终打包是要用release模式

技术分享

 

7.设置Build Active Architecture Only

技术分享

模拟器:iPhone4s~5 : i386 iPhone5s~6plus : x86_64
真机:iPhone3gs~4s : armv7 iPhone5~5c : armv7s iPhone5s~6plus : arm64
如果Build Active Architecture Only设置为YES,那么编译出来的.a静态库就只包含当前设备的指令集。
举个例子:如果我们选择iPhone 5模拟器编译,则编译出来的.a静态库只能用iPhone4s~5模拟器跑程序,用iPhone5s~6plus,则会报找不到x86_64的APPBaseSDK库。
设置为NO,则会把所有指令集的都打包合并。因此静态库有个缺点就是静态库包比源码大很多。

8.设置最低支持版本

技术分享

9.编译生成静态库

编译时,需要用模拟器和真机各编译一次,这样Products目录下的libBaseSDK.a静态库才会变为黑色,右键show in Finder,可以进入Products目录下。

技术分享

10.合并模拟器和真机静态库文件libBaseSDK.a,打开终端命令如下

lipo -create /Users/zhanglinfeng/Library/Developer/Xcode/DerivedData/BaseSDK-cexmrzesjuswutaldkedwjpnpxnk/Build/Products/Release-iphoneos/libBaseSDK.a /Users/zhanglinfeng/Library/Developer/Xcode/DerivedData/BaseSDK-cexmrzesjuswutaldkedwjpnpxnk/Build/Products/Release-iphonesimulator/libBaseSDK.a -output /Users/zhanglinfeng/Desktop/libBaseSDK.a

11.使用.a静态库

将静态库拖入新建的工程,我这里拖到下图箭头所指的UseA文件夹下(如果你要拖到其他目录,就要改Library Search Paths,后面我会介绍Search Paths路径相关知识),再将暴露给外面用的.h文件也拖入工程,

技术分享

技术分享

注意:如果没有include里的.h文件.那就从库的源码中挑出一些需要暴露的.h文件。

导入头文件就可以使用了,如下图

技术分享

注意:如果要用到静态库中的category方法,需要设置Other Linker Flags为-ObjC(注 意大小写,有些资料里大小写搞错了坑死我了)。引入了-ObjC标志,它的作用就是将静态库中所有的和对象相关的文件都加载进来本来这样就可以解决问题 了,不过在64位的Mac系统或者iOS系统下,链接器有一个 bug,会导致只包含有类别的静态库无法使用-ObjC标志来加载文件。变通方法是使用-all_load 或者-force_load标志,它们的作用都是加载静态库中所有文件,不过all_load作用于所有的库,而-force_load后面必须要指定具 体的文件。

四、关于使用库时Search Paths

技术分享

 也许有人会纳闷不用设置search Paths吗,如果你按照我的步骤把静态库拖到工程的相应目录,那就默认设置就可以了。

如果你把静态库放到你喜欢的路径,就要根据静态库在文件夹中的位置设置这个search Paths了。

下图标明了文件夹路径

技术分享

“./”和“$(PROJECT_DIR)”表示当前工程所在文件夹,是一个相对路径,相对该工程在电脑的位置,会自动定位到在当前电脑的绝对路径。如果写绝对路径,工程换了文件夹位置,或换到其他电脑,路径就报错。“../”表示当前工程所在文件夹的上一层文件夹路径。设置路径时两个参数的意义,non-recursive非递归查找,recursive 递归查找 。Search Paths具体例子我另一个博客有iOS 工程套子工程,主工程和framework工程或.a静态库工程联调

 
 

 

iOS 最新framework和.a静态库制作及使用全解

标签:

原文地址:http://www.cnblogs.com/zhanglinfeng/p/5493690.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!