静态库、动态库和Framework的区别?
所谓库就是二进制文件,加上头文件和相关的资源文件就可以提供给别人使用了。
- 静态库:(静态链接库,也叫.a)在编译时会将库copy一份到目标程序中,编译完成之后,目标程序不依赖外部的库,也可以运行,但是缺点就是会使应用程序变大。
- 动态库:(.dylib)编译时只存储指向动态库的引用。可以多个程序指向这个库,在运行时才加载,不会使体积变大,但是运行时加载会损耗部分性能,并且依赖外部的环境,如果库不存在或者版本不正确则无法运行
- Framework:实际上是一种打包方式,将库的二进制文件,头文件和有关的资源文件打包到一起,方便管理和分发。
Framework制作流程
未完待续
Library的制作流程
未完待续
Framework和Library的嵌套使用
我们接下来讨论以下几种情况
- StaticFramework中嵌套StaticFramework
- StaticFramework中嵌套使用StaticLibrary
- StaticLibrary中嵌套StaticLibrary
- DynamicFramework中嵌套使用StaticLibrary
- DynamicFramework中嵌套使用StaticFramework
- DynamicFramework中嵌套使用DynamicFramework
StaticFramework中嵌套StaticFramework
- 创建一个叫做
StaticFrameworkOne
的Framework的静态库(Static Library),并且内部创建一个StaticFrameworkOneTest
的类,并声明staticFrameworkOneTestMethod
方法,内部实现如下:
1 | #import "StaticFrameworkOneTest.h" |
- 同样我们在用同样的方法创建一个名为
StaticFrameworkTwo
的Framework静态库(Static Library),并创建一个StaticFrameworkTwoTest
类,声明一个StaticFrameworkTwoTestMethod
方法,并在StaticFrameworkTwoTest
内部引用了StaticFrameworkOne
,并且调用了StaticFrameworkOneTestMethod
方法,内部实现如下:
1 | #import "StaticFrameworkTwoTest.h" |
- 将编译生成好的StaticFrameworkTwo Framework导入项目中,并调用其
staticFrameworkTwoTestMethod
方法
1 | #import "ViewController.h" |
当我们command + B 编译的时候发现报错了,提示

- 我们在Demo工程加入
StaticFrameworkOne
Framework,再次run工程不再报错,并输出
1 | 2019-05-27 17:23:11.860204+0800 FrameWork制作[8562:334159] -[StaticFrameworkTwoTest staticFrameworkTwoTestMehtod] |
总结:StaticFramework中嵌套使用其他StaticFramework,不会包含内部嵌套的StaticFramwework,只能link其内部的StaticFramework
使用场景:自己的Framework中包含了其他业务也使用的库,为避免最终工程符号冲突或者避免工程多个库文件,采取这种嵌套方式比较合适
StaticFramework中嵌套StaticLibrary
- 创建一个叫做
StaticLibraryOne
的StaticLibrary,并声明方法staticLibraryOneMethod
,内部实现如下:
1 | #import "StaticLibraryOne.h" |
- 将编译好的
libStaticLibraryOne.a
加入StaticFrameworkOne中,并调用其方法,StaticFrameworkOneTest内部实现如下:
1 | #import "StaticFrameworkOneTest.h" |
- 编译StaticFrameworkOne,并将其framework加入测试工程中,并调用其方法:
1 | #import "ViewController.h" |
- 运行测试主工程,输入如下:
1 | 2019-05-27 20:08:44.157571+0800 Framework测试主工程[11412:542791] -[StaticFrameworkOneTest staticFrameworkOneTestMethod] |
总结: StaticFramework中嵌套使用StaticLibrary,会将StaticLibrary中的内容全部link到Framework中,外部使用StaticFramwork时,无需在单独link内部staticLibrary
使用场景: 对外提供一个完成的模块时,使用这种嵌套的方式,但是需要注意,内部嵌套使用StaticLibrary时,最好做了类名方法名全部变量等名称的修改,避免冲突
StaticLibrary中嵌套StaticLibrary
- 创建一个StaticLibraryOne的静态库StaticLibrary,并实现其方法:
1 | #import "StaticLibraryOne.h" |
- 创建一个StaticLibraryTwo的静态库StaticLibrary,并导入StaticLibraryOne,实现其方法
1 | #import "StaticLibraryTwo.h" |
- 编译StaticLibraryTwo,并将其导入测试工程,并调用其方法
1 | #import "ViewController.h" |
- 运行测试主工程,输入如下:
1 | 2019-05-27 20:35:26.567364+0800 Framework测试主工程[11743:577093] -[StaticLibraryTwo staticLibraryTwoTestMethod] |
总结:StaticLibrary的嵌套使用,会link所有内容,但是要注意修改类名,避免冲突
StaticLibrary中嵌套StaticFramework
- 将StaticFrameworkOne加入到StaticLibraryOne并调用其方法
1 | #import "StaticLibraryOne.h" |
- 编译StaticLibraryOne,并将其导入测试工程中,并调用其方法
1 | #import "ViewController.h" |
- 运行测试工程,发现其报错
- 将StaticFramework加入测试工程中,运行测试工程,输出如下:
1 | 2019-05-27 20:54:42.634333+0800 Framework测试主工程[12028:602066] -[StaticLibraryOne staticLibraryOneTest] |
总结:StaticLibrary嵌套使用staticFramework,不会将staticFramework的内容link进来,外部使用还需要link
DynamicFramework中嵌套StaticLibrary
- 创建叫DynamicFrameworkOne的DynamicFramework, 添加StaticLibraryOne,并实现方法:
1 | #import "DynamicFrameworkOneTest.h" |
- 编译DynamicFrameworkOne, 并将其添加到demo工程调用其方法:
1 | #import "ViewController.h" |
- 运行测试工程,输出如下:
1 | 2019-05-27 21:26:06.248994+0800 Framework测试主工程[12571:646020] -[DynamicFrameworkOneTest dynamicFrameworkOneTest] |
总结:dynamicFramework中嵌套使用StaticLibrary,会将StaticLibrary中的内容也link到DynamicFramework内部
注意:测试工程导入DynamicFramework时报错,提示如下:

解决办法:

DynamicFramework中嵌套StaticFramework
- DynamicFrameworkOne中导入StaticFramework,并调用其方法,内部如实现如下:
1 | #import "DynamicFrameworkOneTest.h" |
- 编译DynamicFramework并将其导入到测试主工程:
1 | #import "ViewController.h" |
- 运行测试主工程,输出如下:
1 | 2019-05-27 21:43:59.495934+0800 Framework测试主工程[12852:669931] -[DynamicFrameworkOneTest dynamicFrameworkOneTestMethod] |
总结: DynamicFramework中嵌套使用StaticFramework时,会将StaticFramework中的内容也link到DynamicFramwork内部
DynamicFramework中嵌套DynamicFramework
- DynamicFrameworkTwo中导入 DynamicFrameworkOne,并调用其方法,内部实现如下:
1 | #import "DynamicFrameworkTwoTest.h" |
- 编译DynamicFramework并导入测试工程中,调用其方法,内部实现如下:
1 | #import "ViewController.h" |
- 运行测试工程,发现报错

- 解决方案:将DynamicFrameworkOne导入工程,运行结果如下
1 | 2019-05-27 21:58:46.241110+0800 Framework测试主工程[13102:688871] -[DynamicFrameworkTwoTest dynamicFrameworkTwoTestMethod] |
总结: DynamicFramework中嵌套使用DynamicFramework时,外部使用DynamicFramework时还需要link内部使用的DynamicFramework,具体查看其内部是否有对应的内部DynamicFramework文件
Podfile中#useframework!和useframework!的使用
- 不使用use_frameworks! -> static libraries 方式 -> 生成.a文件
1 | 在Podfile中如不加use_frameworks!,cocoapods会生成相应的 .a文件(静态链接库), |
- use_frameworks! -> dynamic frameworks 方式 -> 生成.framework文件
1 | 使用了use_frameworks!,cocoapods会生成对应的frameworks文件(包含了头文件,二进制文件,资源文件等等) |
使用场景
- Swift项目cocoapods 默认 use_frameworks!
- OC项目cocoapods 默认 #use_frameworks!
用cocoapods导入OC框架到swift项目:
- #use_frameworks! 必须创建头文件,在头文件里面
#import "AFNetworking.h"
- use_frameworks! 如果有头文件,在头文件里面
#import "AFNetworking/AFNetworking.h"
,其它swift文件中用到不需要再import;如果没有头文件,则在每个需要用到的swift文件里import AFNetworking
用cocoapods导入swift框架到swift项目:
- 必须use_frameworks!
- 不需要头文件,在需要用到框架的swift文件里 import Alamofire
用cocoapods导入OC框架到OC项目:
- #use_frameworks! 在需要用到的文件里 #import “AFNetworking.h”;也可以通过pch文件,用法类似swift中的头文件。
- use_frameworks! 与上述类似,用法上没有区别。