【转】iOS静态库 【.a 和framework】【超详细】

原文网址:https://my.oschina.net/kaqijiang/blog/649632

一、什么是库?

库是共享程序代码的方式。

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

二、静态库与动态库的区别?

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

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

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

三、iOS里静态库形式?

.a和.framework

四、iOS里动态库形式?

.dylib和.framework

五、framework为什么既是静态库又是动态库?

系统的.framework是动态库,我们自己建立的.framework是静态库。

六、a与.framework有什么区别?

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

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

.a + .h + sourceFile = .framework。

建议用.framework.

七、为什么要使用静态库?

方便共享代码,便于合理使用。

实现iOS程序的模块化。可以把固定的业务模块化成静态库。

和别人分享你的代码库,但不想让别人看到你代码的实现。

开发第三方sdk的需要。

八、制作静态库时的几点注意:

1注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件+.h+其它资源文件的形式,不同的是,.a本身就是二进制文件,需要我们自己配上.h和其它文件才能使用,而.framework本身已经包含了.h和其它文件,可以直接使用。

2图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。

3category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC。

4如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。

九、创建.a静态库

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

第二步,删除.m文件,保留.h文件, 一般静态库都有一个总的.h文件,方便外部导入头文件。然后导入需要打包的源文件。

第三步,先用真机,编译一次,再用模拟器编译一次。就可以生成.a文件(必须先用真机要不然,不能生成)。

第四步,Xcode生成的.a文件默认没有导出.h文件。需要自己添加。

第五步,导出Products静态库的配置(其实不用设置此步骤,如果真机编译的话,生成导出的时候系统默认会变成Releasse[但是模拟器不会(如果不改这里 得需要把Debug设置为NO)])

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

第六步,合成模拟器的架构【默认:模拟器编译只会生成对应的1种架构,真机编译会合成两种架构】

如果第六步这里,设置为YES,那么编译出来的.a静态库就只包含当前设备的架构。

举个例子:如果我们选择iPhone 5模拟器【Command+B】编译,则编译出来的.a静态库只能用iPhone4s~5模拟器跑程序, 用iPhone5s~6plus,则会报找不到x86_64的libFMDB库。

设置为 NO 之后,【Command+B】不管选择哪个【模拟器】,则都会把【386   : 32位架构   4S ~ 5】【x86_64 : 64位架构   5S ~ 现在的机型】的架构都打包合并。

【注】【真机】不设置 [Build Active Architecture Only] 也默认会自动合并的armv7 和amr64架构 。但是 armv7s架构被苹果放弃了,真机要想合并armv7s的话需要进行如下操作再编译。(其实没必要设置这个)

第七步,合并架构【真机和模拟器】

真机和模拟器合并: lipo -create 静态库1.a(路径) 静态库2.a(路径) -output 新静态库.a

第八步,资源包的问题

1. 静态库的资源, 都应该放到后缀为.bundle的文件夹中 --> 避免文件与本地文件重名被覆盖, 导致加载资源文件出错【注:要加载bundel路径】

2. 静态库打包时, 并不会打包资源文件 --> 需要手动拖出去

一. 经典报错:

找不到符号在XX架构上

Undefined symbols for architecture x86_64(armv7/armv7s/amr64/i386)

二. 架构的分类

1、模拟器架构: 2种

i386   : 32位架构  4S ~ 5

x86_64 : 64位架构   5S ~ 现在的机型

2、真机架构: 3种

armv7 : 32位架构    3GS ~ 4S

armv7s: 特殊的架构   5 ~ 5C   (此架构有问题, 有的程序变得更快, 有的程序变得更慢)

amr64 : 64位架构    5S ~ 现在的机型

64位/32位: 内存寻址不同

三. 如何查看静态库架构

找到Products文件夹, 如果.a文件是黑色, 右键打开 到 Products文件夹

终端中 lipo -info

Generic iOS Device编译出来的OS可用, 有2种架构:armv7/ arm64 (不包含armv7s: 特殊的架构)

iPhone6S模拟器编译出来的: x86_64

iPhone4S模拟器编译出来的: i386

(不设置Build Active Architecture Only的情况下真机编译2种架构, 模拟器编译:对应的1种架构)

四. 合成架构

一般来说, 只需要前两步即可

1. 模拟器架构的合成: Target --> Build Settings --> Build Active Architecture Only(是否只编译当前架构) --> Debug 改为NO(改为NO, 模拟器就可以直接合成2种架构)

2. 真机和模拟器合并: lipo -create 静态库1.a 静态库2.a -output 新静态库.a

3.* armv7s这个架构, 在2014年10月份的xcode版本更新中, 取消了默认导出此架构. 可以不用支持此架构.

如果要支持, 需要手动添加3个架构.

五. Debug和Release版本

一般来说, 我们应该发布的是release版本.

debug:调试版本, 系统本身也会有一些调试代码. 此版本体积会稍大, 运行会稍慢

release: 发布版本, 系统会去除调试代码, 体积变小, 运行速度变快. 对用户来说没有明显的感觉

六. 到底要不要合成多个架构

真机和模拟器合成的好处: 调试会非常方便, 缺点是体积会变大(一种架构就占用一部分体积).

真机和模拟器不合成的好处:体积小,  缺点是调试稍显麻烦.

七. 资源包的问题

1. 静态库的资源, 都应该放到后缀为.bundle的文件夹中 --> 避免文件重名被覆盖, 导致加载资源文件出错

2. 静态库打包时, 并不会打包资源文件 --> 需要手动拖出去

十、创建framework静态库

第一步、新建工程。一般使用工程名就使用库的名称

第二步、导入需要打包的资源文件,同时把资源文件需要外界访问的.h文件导入到系统推荐的.h中

第三步、真机,模拟器编译一下。可能会需要输入AppleID 。导出的文件没有包含.h

第四步、导出.h

第五步、可以查看一下 没合并模拟器架构之前包含几个同.a(可跳过此步)(真机包含两个,模拟器包含一个)

第六步、合成架构【同.a五六步详细看上边】

第七步,合并架构【真机和模拟器】【注意 合并之后的动态/静态库要与原来的名称一致。不然用的时候编译报错】

第八步、动态库变静态库【默认是动态】好处是将来使用时不需要设置添加动态库(也就是下边的方法)

最后步、

Framework制作后, 默认是动态库. 使用时, 需要设置一下: Tarteg --> General --> Embedded Binaries --> 需要添加对应的动态库 【注意 要是制作的时候更改为静态库的话,就不用执行此方法】

谢谢。

时间: 2024-10-21 21:57:36

【转】iOS静态库 【.a 和framework】【超详细】的相关文章

IOS 静态库的和.framework制作

什么是库? 库是程序代码的集合,是共享程序代码的一种方式 根据源代码的公开情况,库可以分为2种类型 开源库 公开源代码,能看到具体实现 比如SDWebImage.AFNetworking 闭源库 不公开源代码,是经过编译后的二进制文件,看不到具体实现 主要分为:静态库.动态库 静态库和动态库的存在形式 静态库:.a 和 .framework 动态库:.dylib 和 .framework 静态库和动态库在使用上的区别 静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝

iOS 静态库,动态库与 Framework

iOS 静态库,动态库与 Framework 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件.另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间. 上面提到库在使用的时候需要

IOS静态库

如何在Xcode中创建C++静态库 http://jingyan.baidu.com/article/03b2f78c111fca5ea237ae26.html iOS 如何创建和使用静态库 http://blog.ibireme.com/2013/09/18/create-ios-static-framework/ iOS开发--创建你自己的Framework http://www.cocoachina.com/ios/20150127/11022.html https://www.raywe

iOS开发——装逼技术精选&全面了解 iOS 静态库开发

全面了解 iOS 静态库开发 简介 在企业开发中,一些核心技术或者常用框架,出于安全性和稳定性的考虑,不想被外界知道,所以会把核心代码打包成静态库,只暴露头文件给程序员使用(比如:友盟.百度地图等第三方的sdk) 静态库和动态库的存在形式 静态库:.a 和 .framework 动态库:.dylib 和 .framework 静态库和动态库的区别 静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统

ios静态库的使用

ios静态库的使用 2014-03-11 22:24 3906人阅读 评论(0) 收藏 举报 ios的静态库文件是*.a,如果需要使用它,我今天学的简单的方法,可通过,简单说说,如果有一个A手机项目,一个B的静态库项目,A想使用B.a,按以下的步骤: 1.在A项目里面拖进B项目.在B的product下面会看见红色的B.a,表示还没有编译通过(在工程设置里添加上你需要导出的.m文件). 2.选择好需要编译的对象,B下的某模拟器或者是B下的真机上进行编译(模拟器上生成的静态库和真机上生成的不能混用)

iOS 8:【转】封装iOS静态库注意事项

源地址:http://fann.im/blog/2014/01/12/ios-static-library/ 做一个 iOS 静态库需要注意的东西: namespace 冲突.静态库用了某第三方库,项目也用了同样的第三方库,在编译的时候就会有 duplicate symbol 错误,因为有两份同样的第三方库.解决办法就是把用到的第三方库加上自定义前缀,包括类名.delegate 协议.常量名,尤其需要注意 Category 的方法名要修改. 封装静态库的时候应尽量避免引入重量级第三方库,多自己进

封装ios静态库碰到的一些问题(二)

在静态库建立好了之后呢,于是应用程序就引用它,加上拷贝的h文件,但是引用之后Build之后提示很多sybmbol 重复 于是进行检查,确实由于是从其他工程修改过来的,很多基础库都引用了,删除之,最后就只剩下xxx.h,死活就是报重复符号,我看来看去都没有 不得其解,后面突然想不过,使用了下definition,发现跳转到了一个文件,里面全部被注释的文件,于是明了,原来偷懒,有的代码是拷贝的,于是h和m文件都在,但是里面内容被注释了,结果xcode不买账啊,直接删除掉,Ok,解决问题 封装ios静

iOS静态库.a文件制作和导入使用

iOS静态库.a文件制作: 1.新建Cocoa Touch Static Library工程 新建工程 - 选择iOS-FrameWork&Libary,选择 Cocoa Touch Static Library工程. 2.Xcode的参数设置 "Build Active Architecture Only" 设置为"NO" "IOS Deployment Target" 设置为 "IOS 7.0" ,表示支持IOS7

ios 静态库冲突的解决办法

最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的时候被“坑”了,最后终于顺利的解决了.发现网上也有不少人遇到一样的问题,但是能找到的数量有限的解决办法写得都不详细,很难让人理解,我来深入的写一写. 我的开发环境 Mac OS X 10.10.1 Xcode 6.1.1 (6A2008a) Cocos2d-x 3.2 新浪微博 SDK for iOS 2015 年 1 月 5 日从 github clone 的版本 遇到的问题 根据新浪微博 SDK 附带的文档接入项目后,