当前位置: 首页 > 编程日记 > 正文

Xcode 创建.a和framework静态库(转)

最近因为项目中的聊天SDK,需要封装成静态库,所以实践了一下创建静态库的步骤,做下记录。

库介绍

库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。
iOS中的静态库有 .a 和 .framework两种形式;动态库有.dylib 和 .framework 形式,后来.dylib动态库又被苹果替换成.tbd的形式。

静态库与动态库的区别

静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。
总结:同一个静态库在不同程序中使用时,每一个程序中都得导入一次,打包时也被打包进去,形成一个程序。而动态库在不同程序中,打包时并没有被打包进去,只在程序运行使用时,才链接载入(如系统的框架如UIKit、Foundation等),所以程序体积会小很多,但是苹果不让使用自己的动态库,否则审核就无法通过。

创建.a静态库

第一步,新建工程。一般使用工程名就使用库的名称,比如我这里用FMDB来创建静态库,我的工程名就取名为FMDB,创建的.a静态库就是libFMDB.a。


使用静态库模板新建工程.png

创建的工程.png


第二步,删除系统默认创建的【FMDB.h】和【FMDB.m】文件,导入需要打包的源文件。


导入源文件后.png


第三步(方式一),修改项目配置


修改配置.png


点击上图中的【3】,弹出的列表中选择【New Headers Phase】,打开【Headers (0 items)】,点击左下角的【+】,选择所有的.h文件。


配置需要暴漏的文件的.h头.png

第三步(方式二),修改项目配置


修改项目配置.png

第四步,修改导出product配置


修改编译配置.png

第五步,修改编译指令集


设置Release为NO.png

模拟器:iPhone4s~5 : i386 iPhone5s~6plus : x86_64
真机:iPhone3gs~4s : armv7 iPhone5~5c : armv7s iPhone5s~6plus : arm64
如果第五步这里,设置为YES,那么编译出来的.a静态库就只包含当前设备的指令集。
举个例子:如果我们选择iPhone 5模拟器【Command+B】编译,则编译出来的.a静态库只能用iPhone4s~5模拟器跑程序,用iPhone5s~6plus,则会报找不到x86_64的libFMDB库。
设置为NO,则会把所有指令集的都打包合并。

第六步,编译(快捷键【Command+B】
编译时,需要用模拟器和真机各编译一次,这样Products目录下的libFMDB.a静态库才会变为黑色,右键show in Finder,可以进入Products目录下。


编译结果.png


为什么需要用模拟器和真机各编译一次呢?
可以看到Products目录下有【Release-iphoneos】和【Release-iphonesimulator】两个文件件。前者里面是真机使用的.a静态库,后者是模拟器使用的.a静态库。

注意:如果步骤四中,不将Build Configuration改为Release,则打包出来的静态库会存于【Debug-iphoneos】和【Debug-iphonesimulator】两个文件夹下。
我们一般都使用Release模式,因为程序最终发布之后是Release版的,所以静态库也是在Release模式下使用。

如果想要通用需要将模拟器使用的静态库与真机使用的静态库合并成一个静态库,可以使用终端命令来实现。命令格式:
lipo -create 第一个.a文件的绝对路径 第二个.a文件的绝对路径 -output 最终的.a文件路径。
本文中使用的命令如下:

lipo -create /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-ctegiztcjikewoeprxxtmryzetfa/Build/Products/Release-iphoneos/libFMDB.a /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-ctegiztcjikewoeprxxtmryzetfa/Build/Products/Release-iphonesimulator/libFMDB.a -output /Users/harvey/Desktop/libFMDB.a

补充:经过多次实践,第三步的操作省略,依然可以导出可正常使用的包。
如果静态库中有category类,则在使用静态库的项目配置中【Other Linker Flags】需要添加参数【-ObjC]或者【-all_load】。

创建framework静态库

第一步,新建项目


新建项目.png


第二步,删除系统默认创建的【FMDB.h】和【FMDB.m】文件,导入需要打包的源文件。


导入源码后的工程.png

第三步,修改项目配置
首先,设置需要暴漏的头文件


header文件设置.png

这里需要注意的是暴露出来的头文件中import的其他类也得添加到public中暴露出来。
如果不想将import的类暴露出来,那么在头文件中用@class 然后在对应的.m文件中再import。

然后设置编译模式,在Xcode菜单【Product】--->【Scheme】--->【Edit Scheme...】中


设置编译模式.png

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


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

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


修改Mach-O 格式.png

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


编译生成的framework静态库.png

第五步,合并模拟器版framework和真机版framework
合并的命令同上面相似,不同之处是:framework静态库合并的不是framework,而是framework下的一个二进制文件,即上一步图中标记的文件。
lipo -create 第一个framework下二进制文件的绝对路径 第二个framework下二进制文件的绝对路径 -output 最终的二进制文件路径。
本文中使用的命令如下:

lipo -create /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-clvayfrjgytqrbdkyqrtcjkxfeuz/Build/Products/Release-iphonesimulator/FMDB.framework/FMDB /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-clvayfrjgytqrbdkyqrtcjkxfeuz/Build/Products/Release-iphoneos/Release-iphoneos.framework/FMDB -output /Users/harvey/Desktop/FMDB

最后将任何一个framework中的二进制文件替换成合并后的二进制文件即可。
把framework添加到要使用的项目中即可使用。

注意:如果创建的framework中使用了category类,则在使用framework的项目配置中【Other Linker Flags】需要添加参数【-ObjC]或者【-all_load】。
如果使用framework的使用出现【Umbrella header for module 'XXXX' does not include header 'XXXXX.h'】,是因为错把xxxxx.h拖到了public中。
如果出现【dyld: Library not loaded:XXXXXX】,是因为打包的framework版本太高。比如打包framework时,选择的是iOS 9.0,而实际的工程环境是iOS 8开始的。

如果创建的framework类中使用了.dylib或者.tbd,首先需要在实际项目中导入.dylib或者.tbd动态库,然后需要设置【Allow Non-modular Includes ....】为YES,否则会报错"Include of non-modular header inside framework module"。


设置【Allow Non-modular Includes ....】.png

补充:打包成的静态库肯定是比源码类要大很多的,因为是由不同指令集不同设备的版本合并成的。所以如果你很在意你的app大小,并且也不是很需要打包成静态库的话,还是用原始类吧。
framework静态库中是可以包含图片资源的;而.a静态库中不能包含图片资源,只能另外创建一个目录存放。

填坑记录

上面的注意里提到了一些坑,以及解决办法。这里再记录一些:
1.framework中用到了NSClassFromString,但是转换出来的class 一直为nil。
先来看一下这个API的官方描述


官方描述.png


什么意思呢?如果转换出来的class为nil,有两种情况:一种情况是这个类不存在;第二种情况是这个类还没有被load。所以一般出现问题,都是第二种情况。
怎么解决这个问题呢?在主工程的【Other Linker Flags】需要添加参数【-ObjC]即可。

2.framework中把图片、音频打包进bundle中,但是一直加载不到。
打包的framework中有一个bundle,bundle里有一些图片、音频等资源。但是用如下方式:

NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"XXXX" ofType:@"bundle"];
NSString *mp3Path = [[NSBundle bundleWithPath:bundlePath] pathForResource:@"Message_system" ofType:@"mp3"];

获取的mp3Path一直为nil。framework,只暴露了一些.h头文件,bundle没有暴露出来,无法获取。那么我们只需要将bundle与framework一起放入目标工程中即可。其实bundle根本不用打包进framework中。
例如:
我们创建了一个叫ABC.framework的静态库。库中使用了Message_system.mp3,那么我们创建一个bundle,命名为ABC.bundle,然后将Message_system.mp3放入bundle中。打包的时候,framework并不包含ABC.bundle。最后在要使用ABC.framework的工程中,新建一个文件夹or group,然后把ABC.framework和ABC.bundle一起拖进去,就可以啦。

Have Fun!

转载于:https://www.cnblogs.com/wwbb/p/7571991.html

相关文章:

软件测试培训需要学习什么

软件测试在近几年引起了很多人的关注,不少人都想要学习软件测试,零基础的学员都会选择报软件测试培训机构学习,那么软件测试需要学习什么呢?来看看下面的详细介绍。 软件测试培训需要学习什么? 软件测试需要学测试环境(网络环境&#xff0c…

IL,Emit之OpCodes说明(备查)

名称说明Add将两个值相加并将结果推送到计算堆栈上。Add_Ovf将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上。Add_Ovf_Un将两个无符号整数值相加,执行溢出检查,并且将结果推送到计算堆栈上。And计算两个值的按位“与”并…

LeetCode实战:只出现一次的数字

背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Given a non-empty array of integers, every element appears twice except for one. Find…

610D - Vika and Segments(线段树+扫描线+离散化)

扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html 看图,图中的数字是横坐标离散后对应的下标,计算时左端点不变,右端点加1,所以总的更新的区间是l到r-1。 也可以理解为1代表的是&#xff…

UI设计比较流行的插画类型和运用

在当代平面设计中,插画是颇为经常使用的展现性元素,是视觉转达的紧张对象。插画在设计作品中,每每用来指导、开导和出现消息,更有针对性地、视觉化地同用户举行交换。真正高效的插画必然是有针对性的,易于辨认的&#…

poj 2362 Square

#include <iostream> //参照poj 1011 sticks#include <algorithm>using namespace std;int sticks[20],visited[20];int flag,total;int t,seg;int cmp(const void* a,const void* b){return (*(const int*)b)-(*(const int *)a);}void solve(int k,int…

Java BIO、NIO、AIO

同步与异步 同步与异步的概念, 关注的是 消息通信机制 同步是指发出一个请求, 在没有得到结果之前该请求就不返回结果, 请求返回时, 也就得到结果了.比如洗衣服, 把衣服放在洗衣机里, 没有洗好之前我们一直看着, 直到洗好了才拿出来晾晒. 异步是指发出一个请求后, 立刻得到了回…

LeetCode实战:数组中的第K个最大元素

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Find the kth largest element in an unsorted array. Note that it is the kth largest el…

热修复测试过程注意事项

软件测试行是近几年比较火热的技术岗位&#xff0c;想要学习软件测试的同学有很多&#xff0c;今天小编给你分析一下关于热修复测试过程注意事项的相关内容&#xff0c;如果你在一次测试中脱颖而出那将来的你一定很精彩! 基于tinker实际测试过程中遇到的问题&#xff0c;小编简…

LeetCode实战:存在重复元素

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Given an array of integers, find if the array contains any duplicates. Your function…

oracle exec 和 call 区别

转自&#xff1a;http://helloaq.iteye.com/blog/221614 exec 和 call 执行一个procedure时&#xff0c; exec是sqlplus的命令&#xff0c;只能在sqlplus中使用。 call是sql命令&#xff0c;任何工具都可以使用转载于:https://www.cnblogs.com/zerocc/archive/2011/07/27/21189…

html简单响应式滚动条置顶

简单响应式滚动条置顶 一般的&#xff0c;让页面出现滚动条的常见方法有&#xff1a; overflow:auto||overflow:scroll 或者overflow-x水平滚动条和overflow-y垂直滚动条那么现在要实现这样的一个效果&#xff1a; 直接在body中给一个header&#xff0c;后面一个Group盒子&…

UI设计培训之:5个小技巧快速学会PS抠图

一听到PS抠图&#xff0c;我们大家心里是不是产生了退却心理&#xff0c;害怕它过于复杂的操作。 那么现在有一种简单方法教给大家&#xff0c;如何在10分钟内快速学会ps抠图。 而你所需要准备的就是给自己10分钟的尝试时间。 你没有尝试过某件事情&#xff0c;就不要轻易说它难…

AIX VNC setup

1. 下载VNC for AIX虽然标明是for AIX51的&#xff0c;但AIX53和AIX61仍可用。 2. 安装RPM: rpm -Uhv vnc-3.3.3r2-3.aix5.1.ppc.rpm 3.编辑配置文件&#xff1a; # which vncserver/usr/bin/X11/vncserver #chmod 777 /usr/binX11/vncserver vi /usr/bin/X11/vncserver 更改前…

历史 history

题目描述 历史学家小&#xff21;正在研究一个奇怪的王国的历史。当前阶段的任务是研究该国的交通。 根据这个奇怪的王国的史书记载&#xff0c;史书开始记载前这个王国有 n 个城市&#xff08;城市从 0 开 始标号&#xff09; &#xff0c;但所有城市之间都没有道路相连。 …

LeetCode实战:Nim 游戏

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 You are playing the following Nim Game with your friend: There is a heap of stones on…

python值得报班学习吗

python值得报班学习吗?最近有很多想要学习Python的同学都会问到这个问题&#xff0c;Python在近几年的发展前景是非常不错的&#xff0c;想要学会Python编程语言&#xff0c;建议还是报班学习&#xff0c;来看看下面的详细介绍吧。 ​  python值得报班学习吗?首先Python值不…

LeetCode实战:2的幂

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Given an integer, write a function to determine if it is a power of two. Example 1: …

P1214 等差数列

https://www.luogu.org/problem/show?pid1214#sub 暴力枚举题&#xff0c;加上一些剪枝。 &#xff08;原谅我卑劣地提交了两个答案特判&#xff09; #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorit…

cocos2d 0.99.5版本屏幕默认是横屏,怎么修改为竖屏呢?

在RootViewController.m文件里面&#xff0c;修改如下代码#elif GAME_AUTOROTATION kGameAutorotationUIViewController // // EAGLView will be rotated by the UIViewController // // Sample: Autorotate only in landscpe mode // // return YES for th…

学习java三个技巧要知道!

java一直是IT行业发展前景非常不错的一门编程语言&#xff0c;学起来是相对有点困难的&#xff0c;尤其是零基础学员&#xff0c;要想学好java技术&#xff0c;一定要知道这三个技巧&#xff0c;来看看下面的详细介绍就知道了。 学习java三个技巧要知道! 1. 树立学习的信心 很多…

LeetCode实战:格雷编码

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 The gray code is a binary numeral system where two successive values differ in only o…

Programmer of Practice Manual

这是我以前再读研究生的时候写的东东&#xff0c;希望搞计算机的同学&#xff0c;教计算机本科生学习技术的文章&#xff08;非算法类&#xff09;粘在这里纪念一下。 大一寒假 结构化编程基础&#xff1a; 图书&#xff1a;《How to C》 实践过程&#xff1a;完成课后的习题&a…

改善C#程序的建议3:在C#中选择正确的集合进行编码

原文:改善C#程序的建议3&#xff1a;在C#中选择正确的集合进行编码要选择正确的集合&#xff0c;我们首先要了解一些数据结构的知识。所谓数据结构&#xff0c;就是相互之间存在一种或多种特定关系的数据元素的集合。结合下图&#xff0c;我们看一下对集合的分类。 集合分类 …

Python工程师求职必知的经典面试题

最近几年&#xff0c;学习Python语言的同学越来越多&#xff0c;学成之后大家对于后期的面试都遇到了很多难题&#xff0c;小编这次为大家整理了一份关于Python工程师求职必知的经典面试题!希望能够帮助到正在找Python工作的同学们。 Python工程师求职必知的经典面试题&#xf…

LeetCode实战:二叉树中的最大路径和

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Given a non-empty binary tree, find the maximum path sum. For this problem, a path i…

为Visual Studio添加配色方案

看到网上有一些教程&#xff0c;他们的代码截图&#xff0c;不是VS默认的白底黑字&#xff0c;觉得挺好看&#xff0c;就也把自己的VS鼓捣了一把&#xff1a; 使用的是现成的配色方案&#xff0c;试了好几种&#xff0c;就觉得这个看着舒服son-of-obsidian.vssettings 你可以去…

黑色星期五阿里云向海淘输出双11技术

本文讲的是"黑色星期五"阿里云向海淘输出双11技术【IT168资讯】11月27日零点&#xff0c;“黑色星期五”正式到来&#xff0c;虽然远在中国的消费者无法参与海外的实体抢购&#xff0c;但电商平台却给了他们从地球另一端参与“大抢购”的机会。随着近年海淘市场的不断…

专业的java培训机构是否靠谱,对比一下就知道了!

java在IT行业的火热是有目共睹的&#xff0c;所以市面上有很多机构都抓住了这点&#xff0c;开设了java培训课程&#xff0c;想要找到一个适合自己的java培训机构&#xff0c;多进行对比就知道了! 专业的java培训机构是否靠谱&#xff0c;对比一下就知道了!专业的Java培训机构靠…

LeetCode实战:环形链表 II

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Given a linked list, return the node where the cycle begins. If there is no cycle, re…