iOS制作动态库Demo,iOS生成Bundle 资源文件包。
如果我们有些功能要给别人用,但是又不想公开代码实现,这时候我们就要打包成库了。库分静态库和动态库两种:
静态库:以.a 和 .framework为文件后缀名。
动态库:以.tbd(之前叫.dylib) 和 .framework 为文件后缀名。
静态库与动态库的区别
静态库:链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝。
动态库:链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序共用(如系统的UIKit.framework等),节省内存。
静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。
静态库 好处:
模块化,分工合作,提高了代码的复用及核心技术的保密程度
避免少量改动经常导致大量的重复编译连接
也可以重用,注意不是共享使用
动态库 好处:
使用动态库,可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,进行分工,影响比较小
使用动态库,多个应用程序共享内存中得同一份库文件,节省资源
使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。
应用插件化
软件版本实时模块升级
iOS8之后,iOS有了App Extesion特性,而且Swift也诞生了。由于iOS主App需要和Extension共享代码,Swift语言机制也需要动态库,于是苹果后来提出了Embedded Framework,这种动态库允许APP和APP Extension共享代码,但是这份动态库的生命被限定在一个APP进程内。简单点可以理解为被阉割的动态库。
但是这种动态库(Embedded Framework) 和系统的 UIKit.Framework 还是有很大区别,传统的动态库是给多个进程用的,而这里的动态库(Embedded Framework)是给单个进程里面多个可执行文件用的。系统的 Framework 不需要拷贝到目标程序中,我们自己做出来的 动态库(Embedded Framework) 哪怕是动态的,最后也还是要拷贝到 App 中(App 和 Extension 的 Bundle 是共享的)。所以苹果没有直接把这种Embedded Framework称作动态库而是叫Embedded Framework。
iOS中的Embedded Framework可以理解为独立的没有main函数的可执行文件。
静态库可以简单理解为一堆目标文件(.o/.obj)的打包体(并非二进制文件),而动态库可以简单理解为 一个没有main函数的可执行文件。
版本
真机-Debug版本
真机-Release版本
模拟器-Debug版本
模拟器-Release版本
Debug
含完整的符号信息,以方便调试
不会对代码进行优化
Release
不会包含完整的符号信息
的执行代码是进行过优化的
的大小会比Debug版本的略小
在执行速度方面,Release版本会更快些(但不意味着会有显著的提升)
下面说下动态库的制作过程:
1.点击File-New-Project
2.输入动态库的名字
3.修改工程文件配置
build setting ->搜索 Mach-O Type -> 修改 Mach-O Type ->Dynamic Library。
4.File->New->Target->Cross-platform->Aggregate,取名为CommonDylib。
5.在其Target Dependencies中`添加SDKDemo。
6.点击下图中的 + 号,选择run script,添加如下脚本
if [ "${ACTION}" = "build" ] then INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework if [ -d "${INSTALL_DIR}" ] then rm -rf "${INSTALL_DIR}" fi mkdir -p "${INSTALL_DIR}" cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/" #ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers" lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}" #open "${DEVICE_DIR}" #open "${SRCROOT}/Products" fi
7.把你制作的SDKDemoBundle.bundle加载到工程中。把你的SDKDemoViewController.m,SDKDemoViewController.h, MBProgressHUD.h和MBProgressHUD.m加载到工程中具体文件自己定义。生成一个SDKDemo.h文件。
代码如下:
#import <UIKit/UIKit.h> //! Project version number for SDKDemo. FOUNDATION_EXPORT double SDKDemoVersionNumber; //! Project version string for SDKDemo. FOUNDATION_EXPORT const unsigned char SDKDemoVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import <SDKDemo/PublicHeader.h> #import<SDKDemo/SDKDemoViewController.h>
8.设置公开头文件。点击下图(9步骤中的图)的加号可以加入公开文件。若你是把原来的目录拖入工程的需要自己加文件。强力建议直接把文件或文件夹拷贝到工程目录下直接加载,那么他们的头文件自动加入到工程头文件中(Header下)。.m文件自动加入到Compile Sources下。
9.加入头文件后这个样子都在工程目录下需要,需要把它移动到公开头文件区域
10.编译SDK
分别将sdk在模拟器(随便选一款模拟器)和Generic iOS Device下编译 (选择该target,command + B)。这会编译生成2个SDK,一个适用于模拟器,一个适用于真机。
10.可以看到Products下的SDKDemo.framework由红变黑。
Debug-iphoneos文件夹下的是真器使用的动态库文件,Debug-iphonesimulator文件夹下的是模拟器使用的动态库文件。
12.若需要生成发布的动态库,需要修改环境设置Release,在Generic iOS Device下编译 (选择该target,command + B)生成发布版本的动态库。