iOS 静态库,动态库与 Framework

iOS 静态库,动态库与 Framework

静态库与动态库的区别

首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。

什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件。另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间。

上面提到库在使用的时候需要 Link,Link 的方式有两种,静态和动态,于是便产生了静态库和动态库。

静态库

静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之所以叫做静态,是因为静态库在编译的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。

静态库的好处很明显,编译完成之后,库文件实际上就没有作用了。目标程序没有外部依赖,直接就可以运行。当然其缺点也很明显,就是会使用目标程序的体积增大。

动态库

动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来。

动态库的优点是,不需要拷贝到目标程序中,不会影响目标程序的体积,而且同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库)。同时,编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。动态库带来的问题主要是,动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境。如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行(Linux 下喜闻乐见的 lib not found 错误)。

iOS Framework

除了上面提到的 .a 和 .dylib 之外,Mac OS/iOS 平台还可以使用 Framework。Framework 实际上是一种打包方式,将库的二进制文件,头文件和有关的资源文件打包到一起,方便管理和分发。

在 iOS 8 之前,iOS 平台不支持使用动态 Framework,开发者可以使用的 Framework 只有苹果自家的 UIKit.Framework,Foundation.Framework 等。这种限制可能是出于安全的考虑(见这里的讨论)。换一个角度讲,因为 iOS 应用都是运行在沙盒当中,不同的程序之间不能共享代码,同时动态下载代码又是被苹果明令禁止的,没办法发挥出动态库的优势,实际上动态库也就没有存在的必要了。

由于上面提到的限制,开发者想要在 iOS 平台共享代码,唯一的选择就是打包成静态库 .a 文件,同时附上头文件(例如微信的SDK)。但是这样的打包方式不够方便,使用时也比较麻烦,大家还是希望共享代码都能能像 Framework 一样,直接扔到工程里就可以用。于是人们想出了各种奇技淫巧去让 Xcode Build 出 iOS 可以使用的 Framework,具体做法参考这里这里,这种方法产生的 Framework 还有 “伪”(Fake) Framework 和 “真“(Real) Framework 的区别。

iOS 8/Xcode 6 推出之后,iOS 平台添加了动态库的支持,同时 Xcode 6 也原生自带了 Framework 支持(动态和静态都可以),上面提到的的奇技淫巧也就没有必要了(新的做法参考这里)。为什么 iOS 8 要添加动态库的支持?唯一的理由大概就是 Extension 的出现。Extension 和 App 是两个分开的可执行文件,同时需要共享代码,这种情况下动态库的支持就是必不可少的了。但是这种动态 Framework 和系统的 UIKit.Framework 还是有很大区别。系统的 Framework 不需要拷贝到目标程序中,我们自己做出来的 Framework 哪怕是动态的,最后也还是要拷贝到 App 中(App 和 Extension 的 Bundle 是共享的),因此苹果又把这种 Framework 称为 Embedded Framework

Swift 支持

跟着 iOS8 / Xcode 6 同时发布的还有 Swift。如果要在项目中使用外部的代码,可选的方式只有两种,一种是把代码拷贝到工程中,另一种是用动态 Framework。使用静态库是不支持的。

造成这个问题的原因主要是 Swift 的 Runtime 没有被包含在 iOS 系统中,而是会打包进 App 中(这也是造成 Swift App 体积大的原因),静态库会导致最终的目标程序中包含重复的 Runtime(这是苹果自家的解释)。同时拷贝 Runtime 这种做法也会导致在纯 ObjC 的项目中使用 Swift 库出现问题。苹果声称等到 Swift 的 Runtime 稳定之后会被加入到系统当中,到时候这个限制就会被去除了(参考这个问题 的问题描述,也是来自苹果自家文档)。

CocoaPods 的做法

在纯 ObjC 的项目中,CocoaPods 使用编译静态库 .a 方法将代码集成到项目中。在 Pods 项目中的每个 target 都对应这一个 Pod 的静态库。不过在编译过程中并不会真的产出 .a 文件。如果需要 .a 文件的话,可以参考这里,或者使用 CocoasPods-Packager这个插件。

当不想发布代码的时候,也可以使用 Framework 发布 Pod,CocoaPods 提供了vendored_framework 选项来使用第三方 Framework,具体的做法可以参考这里这里

对于 Swift 项目,CocoaPods 提供了动态 Framework 的支持,通过use_frameworks! 选项控制。

更多有关代码分发的扩展资料可以参考这篇博客: http://geeklu.com/2014/02/objc-lib/

参考资料

时间: 2024-07-31 23:19:34

iOS 静态库,动态库与 Framework的相关文章

ios 开发中 动态库 与静态库的区别

使用静态库的好处 1,模块化,分工合作 2,避免少量改动经常导致大量的重复编译连接 3,也可以重用,注意不是共享使用 动态库使用有如下好处: 1使用动态库,可以将最终可执行文件体积缩小 2使用动态库,多个应用程序共享内存中得同一份库文件,节省资源 3使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的. 从1可以得出,将整个应用程序分模块,团队合作,进行分工,影响比较小. 等其他好处, 从2可以看出,其实动态库应该叫共享库,那么从这个意义上来说,苹果禁止iOS开

Xcode4.6创建和使用iOS的dylib动态库(转载)

此为xcode4的方法,xcode3的方法请查看 Xcode3创建和使用iOS的dylib动态库 找到两个目录,最好用两个finder窗口分别打开: 目录一: [plain] view plaincopy /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/ 目录二: [plain] view plaincopy /Applica

静态、动态库制作使用

本质 库是一种可执行代码的二进制格式,可以被载入内存中执行 库分静态库和动态库两种. 一.概念 静态函数库 库的名字一般是libxxx.a 函数库的链接是在编译时期完成 所有相关对象与牵涉的函数库被链接合成一个可执行文件 运行时,与函数库再无瓜葛 动态函数库 库的名字一般是libxxx.so 函数库的链接是在运行时期完成 运行时,在运行环境中必须有相应的库 二.优缺点 静态函数库缺点 文件较大,浪费空间 库或者程序一方改变都使得重新编译 动态函数库优点 文件较小,节省空间. 库具有公用性,内存中

C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

目录 0. 引言 1. 交叉编译 2. Cygwin简介 3. 静态库编译及使用 4. 动态库编译及使用 5. MinGW简介 6. CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统.linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统.为什么linux和unix之间有很多软件可以很轻松的移植?因为linux也满足POSIX规范,所以在运行机制上跟unix相近.同时,POSI

018_C语言静态库动态库

 linux下C语言编程环境 头文件目录:/usr/include/ 库目录:/usr/lib/ 动态库与静态库的区别:在计算机程序源代码需要通过翻译.汇编.链接过程而生成可执行文件,再由加载器加载到内存,两者区别就在于程序加载时链接到相应库的方式不同,程序编译时指定了静态库,编译后可直接运行,而编译时指定动态库时,编译后还要先指定库的路径. 静态库: ar -rs libmy_math.a *.o 生成静态库libmy_math.a ar -t 查看静态库 gcc test.c -L. -

windows库的创建和使用:静态库+动态库

windows库的创建和使用:静态库+动态库 一.静态库的创建和使用 1. 静态库创建 (1)首先创建工程test,测试代码如下: 1) test.h void test_print(); 2) test.cpp #include "test.h" #include <stdio.h> void test_print() { printf("test_print in static lib."); } 3)右击工程test:属性-->配置属性--&

Linux 静态库&amp;动态库调用

1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不兼容的.本文仅限于介绍linux下的库.2.库的种类linux下的库有两种:静态库和共享库(动态库).二者的不同点在于代码被载入的时刻不同.静态库的代码在编译过程中已经被载入可执行程序,因此体积较大.共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小.3.库存在

C++开发新版本vs使用旧版本vs编译的静态库动态库

关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成它时所用的同一工具集进行链接.即若在编译静态库时开启了全程序优化,那么编译出的静态库不可移植. 2. 在 Visual Studio 2013 及更低版本中,不能保证使用不同编译器工具集和运行时库版本生成的对象文件 (OBJ).静态库 (LIB).动态库 (DLL) 和可执行文件 (EXE) 之间的

iOS中创建动态库及调用方法

去年因需要用到动态库,自己就找了好多一些 资料,最终找到了一套方法,怎么创建与使用动态库,记录一下: Xcode提供了在iOS工程中创建静态库的功能,和在MAC上创建动态库和静态库的功能. 但是没有提供在iOS工程中创建动态库的功能(苹果官方不允许程序中存在动态库链接,这样的程序会被AppStore拒),如下图:  由于苹果不支持自己创建iOS动态库,所以要想创建动态库首先要修改Xcode的配置文件使其支持具备创建iOS 动态库的功能, 经过调研和查询网上的一些资料,并经过自己测试成功,以下是修

静态库 动态库

1,存在形式 静态库: .a 和 .framework; 动态库: .dylib 和 .framework; 2. 使用 静态库: 链接时,静态库会完整的复制到可执行文件中,被多次使用就会用多份冗余拷贝; -- (核心代码,将MRC打包成静态库,避免切换开发环境) 动态库: 链接时,不复制,程序运行时 由系统动态加载到内存, 供程序调用. [注意]: 静态库并不会将资源打包, 如果静态库中用到了其他的资源,必须手动导入.(一般将资源放入到.bundle文件中) 3. 报错 Undefined s