Xcode7 中创建静态库:.a 和 .framework

一、简单介绍

1.什么是库?

  库是程序代码的集合,是共享程序代码的一种方式

2.库的分类

  根据源代码的公开情况,库可以分为2种类型

  (1)开源库

    公开源代码,能看到具体实现

    比如SDWebImage、AFNetworking

  (2)闭源库

    不公开源代码,是经过编译后的二进制文件,看不到具体实现

    主要分为:静态库、动态库

二、静态库和动态库

1.静态库和动态库的存在形式

静态库:.a 和 .framework

动态库:.dylib 和 .framework

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

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

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

三、静态库简介:

1、静态库分为:

真机—Debug(调试)版本、

真机—Release(发布)版本、

模拟器—Debug版本、

模拟器—Release版本;

开发中一般都打包Release(发布)版本,将真机和模拟器版本合并,提供外界。

2、使用场景:在项目开发的过程中,例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成静态库,别人只能调用接口,而不能知道其中实现的细节。

四、用Xcode7创建.a静态库

.a文件版本(以制作SDWebImage静态库为例)

1、新建项目,点击iOS—Framework&—Cocoa Touch Static Library。

给你的工程命名为SDWebImageStaticLib

2、系统自动生成以工程名命名的.h和.m文件,可自定义的在目录下添加或删除文件,注意目录下Products文件夹有一个.a文件为红色,说明文件并不存在,需要接下来的处理就是将是自己写的库文件中所有的.m文件都放入.a文件中私有隐藏起来。

这里我们将系统生成的.h和.m文件删除。

3.选中TARGETS下的库文件名,创建对外暴露的头文件

创建完之后

4.将SDWebImage下的所有文件导入到SDWebImageStaticLib下

注意:第三步骤和第四步骤是可以调换的,只不过调换后需要手动的将需要暴露的头文件添加进去,所以不调换可以帮助我们完成。

此时默认的情况下,暴露的头文件都在Project下,应该移动到Public下

之前:

移动后:

5、然后点击左上角,选择Edit Scheme,Build Configuration下选择Release,先注意检查下面Release是否为NO:Yes表示只编译选中模拟器设备对应的架构,No则为编译所有模拟器设备支持的cup架构(Debug版本同理),选择NO,然后分别在模拟器和真机下Command+B编译一下,会看到Products文件夹下的.a文件变为黑色,这个.a文件就是我们想要得到的静态库,这里会出现一个问题你先编译的模拟器会发现.a依然是红色,你需要模拟器和真机都编译后.a才会变成黑色,这应该是Xcode本身的问题。

<1>

<2>

<3>

这3步设置完后,选择真机模式编译一下,Command + B,此时看到.a静态库文件变成了黑色。

然后将上面的第<3>步改为Debug,再选择模拟器编译一下,Command + B,就创建了模拟器环境下的.a文件,截图如下一样。

可以在终端看到,真机Release发布模式和模拟器Debug测试模式的.a文件都存在

文件为:

6、合并真机和模拟器.a文件,在终端输入以下命令行:lipo -create  模拟器.a文件的路径 真机.a文件的路径 -output 合并后的保存路径(最终会得到一个合并后的libSDWebImageStaticLib.a文件,再将暴露出来的.h头文件一起复制出来。

7、使用:只需将libSDWebImageStaticLib.a和暴露出来的.h头文件导入工程目录下就可供外界使用,这样就很好的保护了自己的实现源代码,不被他人篡改和偷窃。

8.这里再补充一下:

<1>.文件大小.a文件的体积(一般情况下)

  真机用的.a > 模拟器用的.a

  所合成.a == 真机用的.a + 模拟器用的.a

<2>.

注:关于静态库对CPU架构的支持,首先了解iOS设备CPU架构方面的知识,ARM是微处理器行业的一家知名企业,arm处理器以体积小和高性能的优势在嵌入式设备中广泛使用,几乎所有手机都是使用它的。

模拟器:iphone4s~5 : i386 iphone5s~6plus : x86_64

真机:iphone3gs~4s : armv7  iphone5~5c : armv7s (静态库只要支持了armv7,就可以跑在armv7s的架构上) iphone5s~6plus : arm64

armv6, armv7, armv7s是ARM CPU的不同指令集,原则是向下兼容的。例如iPhone4S CPU支持armv7, 但它同时兼容armv6,只是使用armv6指令可能无法充分发挥它的特性。

查看静态库.a对处理器架构的支持,先cd到.a文件的路径下,命令行输入:lipo -info xxxxx.a

<3>.

如果库中还包含了一些资源文件(如图片等),那么资源文件也应该放在上面的文件夹中。

五、用Xcode7创建.framework静态库,以MJRefresh为例

1.新建工程并选择默认Target为Cocoa Touch Framework, 如图:

2.给你的工程命名为MJRefresh,生成的静态库将以标准的名称格式出现.即MJRefresh.framework

3、项目自动创建设置开放的头文件和存放资源的Bundle文件,可以看到一个红色的MJRefresh.framework空的静态库

4、删除自动生成的MJRefresh.h文件

5、导入MJRefresh框架中的所有文件,应该暴露出来的.h文件默认都在Project下

6、.framework中有些类可能是一些私有的辅助工具,不需要使用者看到,在这里只需要把开放出去的类放到Public下, 如图

7、然后选择模拟器和Debug模式,编译一下,Command + B,此时,虽然看到MJRefresh.framework仍为红色,其实已经生成能在模拟器上运行的.framework静态库,进入MJRefresh.framework目录文件下,以及使用终端可以看到生成的静态库。

选中静态库文件,获取绝对路径如下:

 

在目录下和终端可以看到生成的静态库

8、再选择真机,设置Release模式,编译一下,Command + B,此时,虽然看到MJRefresh.framework变成黑色,生成能在真机上运行的静态库文件。

在目录下和终端可以看到生成的静态库

9、我们随意选择一个静态库,点进去看这个库文件中的具体内容,可以看到一个MJRefresh可执行二进制的文件,资源MJRefresh.bundle,暴露出去的头文件Headers等

10、下面一步就是合并了,生成模拟器和真机环境下通用的二进制可执行文件MJRefresh,生成后看一下这个可执行文件使用的微处理器架构有哪些:

 

11.好了,合作完成,剩下的就是如何使用这个.framework静态库了。

(1)我们可以随意选择一个生成的MJRefresh.framework,拷贝一下到桌面

(2)然后再将合并后生成的可执二进制文件MJRefresh拷贝一下,粘贴到桌面上这个MJRefresh.framework文件中,替换里面的MJRefresh,生成一个完成的静态库。

(3)打开MJRefresh.framework/Modules/module.modulemap文件,可以看到暴露的MJRefrsh.h文件被放在umbrella雨伞下保护起来了,所以我们需要将其他的所有暴露的.h文件放到MJRefresh.h文件中保护起来,不然会出现警告

(4)我们以为此时大功告成,可以测试代码了,结果出现如下错误:

为什么会这样的?因为我们做的是静态库,在使用的时候需要额外加一个步骤,要把Framework同时添加到‘Embedded Binaries’中

此时再测试,发现没问题了,大功告成,可喜可贺!

六、制作静态库的注意点

(1)注意:

  无论是 .a 静态库还是 .framework 静态库,最终需要的都是:二进制文件 + .h + 其它资源文件

(2).a 和 .framework 的使用区别

  .a 本身是一个二进制文件,需要配上 .h 和 其它资源文件 才能使用

  .framework 本身已经包含了 .h 和 其它资源文件,可以直接使用

(3)图片资源的处理

  如果静态库中用到了图片资源,一般都放到一个bundle文件中,bundle名字一般跟 .a 或 .framework 名字一致

  bundle的创建:新建一个文件夹,修改扩展名为 .bundle 即可,右击bundle文件,显示包内容,就可以往bundle文件中放东西

  建议:自己制作的静态库中要用到的图片资源,不建议直接以png的后缀名方式拖到项目中使用,而是推荐使用放到bundle文件中。这样可以避免静态库的图片名和使用静态库的项目中存在的图片产生冲突。

  1)新建一个文件夹,把需要打包的资源图片放在里面

例如:

    

  2)修改扩展名为 .bundle,敲回车,点击添加。

例如:

(4)多文件处理

  如果静态库需要暴露出来的 .h 比较多,可以考虑创建一个主头文件(一般 主头文件 和 静态库 同名)

  在主头文件中包含所有其他需要暴露出来的 .h 文件

  使用静态库时,只需要#import 主头文件

  实际上苹果官方就是这么做的,例如:#import <UIKit/UIKit.h>

(5).framework为什么既是静态库又是动态库

  系统的 .framework 是动态库

  我们自己建立的 .framework 是静态库

(6)静态库中包含了Category(分类)

如果静态库中包含了Category,有时候在使用静态库的工程中会报“方法找不到”的错误(unrecognized selector sent to instance

解决方案:在使用静态库的工程中配置Other Linker Flags为-ObjC

iOS:Xcode7下创建 .a静态库 和 .framework静态库的更多相关文章

  1. iOS开发中静态库之".framework静态库"的制作及使用篇

    iOS开发中静态库之".framework静态库"的制作及使用篇 .framework静态库支持OC和swift .a静态库如何制作可参照上一篇: iOS开发中静态库之" ...

  2. iOS静态库转Framework动态库

    参考文章: iOS静态库(.a 和framework)  XCode6制作动态及静态Framework  说说iOS中静态库的开发  dyld: Library not loaded: @rpath/ ...

  3. 【转】 iOS 开发之静态库.a和动态库详解 -- 不错

    原文网址:http://blog.csdn.net/lxl_815520/article/details/52154331 一, 简单介绍 1.什么是库 库是程序代码的集合,是共享程序代码的一种方式 ...

  4. iOS 静态库,动态库与 Framework 浅析

    静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人 ...

  5. IOS静态库和Framework区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系 ...

  6. iOS 静态库,动态库与 Framework

    iOS 静态库,动态库与 Framework     静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢 ...

  7. iOS静态库及Framework 创建

    本文转自cocoachina,尊重作者的汗水. 讲述的非常透彻,有需要的朋友可以阅读实践.转载请注明出处 //=================以下留着备份==================// 在 ...

  8. iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用

    iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用 前言 开发中经常使用三方库去实现某特定功能,而这些三方库通常又分为开源库和闭源库.开源库可以直接拿到源码,和自 ...

  9. ios中静态库的创建和使用、制作通用静态库(Cocoa Touch Static Library)

    创建静态库可能出于以下几个理由: 1.你想将工具类代码或者第三方插件快捷的分享给其他人而无需拷贝大量文件.2.你想让一些通用代码处于自己的掌控之下,以便于修复和升级.3.你想将库共享给其他人,但不想让 ...

随机推荐

  1. echarts图表自适应浏览器窗口的大小

    echarts问题描述 当浏览器窗口发生变化时,echarts图表未能自适应浏览器的变化,产生如下的效果 解决方案 在$(function(){}中添加 window.onresize = funct ...

  2. iOS开发-Runloop详解(简书)

    不知道大家有没有想过这个问题,一个应用开始运行以后放在那里,如果不对它进行任何操作,这个应用就像静止了一样,不会自发的有任何动作发生,但是如果我们点击界面上的一个按钮,这个时候就会有对应的按钮响应事件 ...

  3. 利用php设置url转发 - 解决空间不提供子目录绑定功能的问题

    由于很多新手都是使用的虚拟空间都是最便宜的那种,这空间一般不支持子目录绑定.但是很多朋友又想设置几个不同的二级域名访问不同的网站程序.于是大家找到了域名url转发,但是由于国家政策的原因,许多服务商暂 ...

  4. maven修改本地仓库默认路径问题

    找到maven本地路径的settings.xml文件,如D:\Program Files\apache-maven-3.0.5\conf\settings.xml: 在settings.xml文件中增 ...

  5. 工作中常用Linux命令--服务器运维

    工作中常用Linux命令--服务器运维 lsof查看端口使用情况 lsof -i:8080更多lsof命令使用说明:http://www.cnblogs.com/peida/archive/2013/ ...

  6. 执行监听器( Execution listener)

    相关类: org.activiti.engine.delegate.ExecutionListener org.activiti.engine.delegate.TaskListener org.ac ...

  7. 使用 gulp 压缩 CSS

    请务必理解如下章节后阅读此章节: 安装 Node 和 gulp 使用 gulp 压缩 JS 压缩 css 代码可降低 css 文件大小,提高页面打开速度. 我们接着将规律转换为 gulp 代码 规律 ...

  8. php中的int参数

    PHP的函数有很多都会有一个int参数,这些参数基本都是定义为一个常量,虽然不知道有啥用,先记录一下 他们对应的数字 1. htmlspecialchars(),htmlentities() http ...

  9. ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

  10. ( 转 ) UML 类图

    在UML类图中,常见的有以下几种关系:泛化(Generalization),  实现(Realization),关联(Association),聚合(Aggregation),组合(Compositi ...