【转】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 --> 需要添加对应的动态库 【注意 要是制作的时候更改为静态库的话,就不用执行此方法】
谢谢。
【转】iOS静态库 【.a 和framework】【超详细】的更多相关文章
- linux下编译qt5.6.0静态库——configure配置(超详细,有每一个模块的说明)(乌合之众)
linux下编译qt5.6.0静态库 linux下编译qt5.6.0静态库 configure生成makefile 安装选项 Configure选项 第三方库: 附加选项: QNX/Blackberr ...
- iOS 静态库,动态库与 Framework
iOS 静态库,动态库与 Framework 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢 ...
- iOS静态库转Framework动态库
参考文章: iOS静态库(.a 和framework) XCode6制作动态及静态Framework 说说iOS中静态库的开发 dyld: Library not loaded: @rpath/ ...
- IOS静态库
如何在Xcode中创建C++静态库 http://jingyan.baidu.com/article/03b2f78c111fca5ea237ae26.html iOS 如何创建和使用静态库 http ...
- iOS - 静态库的创建与使用
在日常项目开发中,不论是为了两个公司项目上的业务交流还是为了减少项目的编译时间,有的时候我们会把项目中的私密内容打包成静态库,或者是把项目中变动较少一部分打包成静态库以便提高编译效率,那么下面我们就来 ...
- iOS静态库 ---iOS-Apple苹果官方文档翻译
iOS静态库 ---iOS-Apple苹果官方文档翻译 •什么是库? 库是共享程序代码的方式,一般分为静态库和动态库.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使⽤用就为什 ...
- iOS静态库.a文件制作和导入使用
iOS静态库.a文件制作: 1.新建Cocoa Touch Static Library工程 新建工程 - 选择iOS-FrameWork&Libary,选择 Cocoa Touch Stat ...
- iOS静态库的制作与引用
[iOS静态库的制作与引用] 1.Configuring Exported Headers To configure which headers are exported to clients, se ...
- 判断IOS静态库(.a文件)是否支持模拟器和真机运行
判断IOS静态库(.a文件)是否支持模拟器和真机运行 在mac终端下,进入到.a文件目录下,然后输入: lipo -info libMyAlertView.a Architectures in the ...
随机推荐
- c# access插入null值
c# 插入access数据库 提示错误: Parameter @DeviceLocation has no default value. 参数@DeviceLocation 的有没有默认值. Stri ...
- php无缝连接滚动
最近用到了,仿照别人的写了一个 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...
- Canopy使用教程 (3)
1. 2. plot函数: plot默认生成是曲线图,可以通过kind参数生成其他的图形,可选的值为:line, bar, barh, kde, density, scatter. 散点图.使用kin ...
- hdu 2053
Ps:找规律题....凡是平方数都是开...WA了一次..数组给的太小?...后来给到3000..就AC了 代码: #include "stdio.h"long long dp[3 ...
- PP
- php大力力 [025节] 来不及学习和分类的,大力力认为有价值的一些技术文章合集(大力力二叔公)(2015-08-27)
php大力力 [025节] 来不及学习和分类的,大力力认为有价值的一些技术文章合集(大力力二叔公)(2015-08-27) 比较好的模版 免费模板网,提供大量DIV+CSS布局网页模板下载及后台管理 ...
- Ubuntu 开启ssh
sudo apt-get install openssh-server Ubuntu缺省安装了openssh-client,所以在这里就不安装了,如果你的系统没有安装的话,再用apt-get安装上即可 ...
- Android AIDL使用详解
1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间 ...
- HDU 4576
http://acm.hdu.edu.cn/showproblem.php?pid=4576 题意:给一个1-n的环,m次操作,每次操作顺时针或逆时针走w步,求最后落在[l,r]区间的概率 dp[i] ...
- windows服务创建与管理
安装windows 服务 C:\Users\chensimin>cd \ C:\>cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 C:\W ...