xcode 详解创建静态库和动态库的方法

发布时间 - 2026-01-10 22:34:17    点击率:

xcode 创建静态库和动态库

1、linux中静态库和动态库区别:

库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。

静态库:这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

动态库:这类库的名字一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。

2、iOS开发中静态库和动态库区别:

静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。

静态库 好处:

i.模块化,分工合作,提高了代码的复用及核心技术的保密程度

ii.避免少量改动经常导致大量的重复编译连接

iii.也可以重用,注意不是共享使用

动态库 好处:

i.使用动态库,可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,进行分工,影响比较小

ii.使用动态库,多个应用程序共享内存中得同一份库文件,节省资源

iii.使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。

iv.应用插件化

v.软件版本实时模块升级

vi.共享可执行文件 在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,iOS仍然不允许进程间共享动态库,即iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。 不过iOS8上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。

3、xcode创建静态库

打开Xcode, 选择File ----> New ---> Project。 新建工程。 选择iOS ----> Framework & Library ---> Cocoa Touch Static Library。 点击Next。创建工程: 

新增2个类作为我们的一个静态类文件: 

其中LogLib.h的代码如下:(作为公开存在) 

LogLib.m实现方法如下,变成静态库后该文件隐藏: 

然后选择真机进行静态库的创建:(command + B) 

这个时候会出现如下的错误提示: 

按照错误的提示得知我们需要在iOS8.1下build需要选择证书: 

好了,在Product下会存在libStaticLib.a文件:  

这只是真机下的一个静态库,同样选择模拟器,command + B,生成模拟器下的静态库。

找到这2个新建的静态库文件:  

分别用2个.a加入到其他项目在不同运行坏境选择不同的.a静态库明显不明智,打开终端,输入以下命令行进行整合:

lipo -create 真机.a路径 模拟器.a路径 -output 整合的.a路径

lipo -create /Users/fangdd/Library/Developer/
Xcode/DerivedData/StaticLib-ercfdooewtvlxmakqvyxkohcagph
/Build/Products/Debug-iphoneos/libStaticLib.a /Users/fangdd
/Library/Developer/Xcode/DerivedData/StaticLib-ercfdooewtvlxmakqvyxkohcagph
/Build/Products/Debug-iphonesimulator/libStaticLib.a -output /Users/fangdd/Desktop/staticLib.a

会在 整合的.a路径下找到合体的静态库。

将生产的静态库及相应的头文件加入到我们的测试项目中,运行得到:  

完毕.

4、xcode创建动态库

打开Xcode, 选择File ----> New ---> Project。 新建工程。 选择iOS ----> Framework & Library ---> Cocoa Touch Framework。 点击Next。创建工程: 

命名为DymicLib:  

同样的添加新的2个类作为测试:  

将头文件作为公共的头文件,提供给外部调用:  

运行后变生成了一个动态库,找到Product下的DymicLib.framework所在的目录:  

注意这个只是运行坏境下的动态库(模拟器和真机),下面建立新的TARGETS:命名为CommonDymicLib: 

将之前生成的DymicLib加入到新的CommonDymicLib中:  

CommonDymicLib添加新的脚本来实现模拟器和真机合并:  

脚本如下:

# Sets the target folders and the final framework product.
FMK_NAME=${PROJECT_NAME}

# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework

# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/$ {FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework

# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
# 分别编译生成真机和模拟器使用的framework
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build

# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi

mkdir -p "${INSTALL_DIR}"

cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"

# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
# 使用lipo命令将其合并成一个通用framework
# 最后将生成的通用framework放置在工程根目录下新建的Products目录下
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"

rm -r "${WRK_DIR}"

选择iOS Device运行: 

找到生成的CommonDymicLib下的动态库DymicLib.framework: 

在测试项目中将DymicLib.framework加入:  

运行即可!

心得:这个时候所谓的动态库其实意义就是升级版的静态库,因为动态库使用的前提是项目在发布前添加到项目中,这和我们所谓的插件(即插即用,随时在自己的服务器上下载一个动态库运行,而不需要重新打包,我们可以选择在需要的时候再加载动态库)完全是两码事。

插件实现方式:使用dlopen加载动态库,动态库中真正的可执行代码为DymicLib.framework/DymicLib文件,因此使用dlopen时如果仅仅指定加载动态库的路径为DymicLib.framework是没法成功加载的。将我们创建的动态库放在我们的服务器,项目上线后再下载这个动态库到我们的Documents文件夹中,使用如下代码动态使用动态库:

#import <dlfcn.h> 
 
NSString *documentsPath = [NSString stringWithFormat:@"%@/Documents/DymicLib.framework/DymicLib",NSHomeDirectory()]; 
voidvoid * libHandle = NULL; 
libHandle = dlopen([documentsPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW); 
if (libHandle == NULL) { 
 charchar *error = dlerror(); 
 NSLog(@"dlopen error: %s", error); 
} else { 
 NSLog(@"dlopen load framework success."); 
} 

使用  动态库 中的类:

Class rootClass = NSClassFromString(@"DymicLog"); 
if (rootClass) { 
 id object = [[rootClass alloc] init]; 
 [(DymicLog *)object relog:@"hello world"]; 
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# xcode  # 创建静态库和动态库  # 静态库和动态库的创建  # 静态库和动态库创建详解  # Linux动态库函数的详解  # Linux静态库与动态库实例详解  # 详解dll动态库的开发与调用及文件的读写小程序  # android studio2.3如何编译动态库的过程详解  # Linux下g++编译与使用静态库和动态库的方法  # Linux环境g++编译GDAL动态库操作方法  # 解决Linux程序编译链接动态库版本的相关问题  # 浅谈Linux C语言动态库及静态库  # c++实现加载so动态库中的资源  # linux 程序、动态库、静态库内部添加版本号和编译时间详解  # 从源码编译Android系统的Java类库和JNI动态库的方法  # C#调用非托管动态库中的函数方法  # Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法  # 动态库调用静态库示例讲解  # linux生成(加载)动态库静态库和加载示例方法  # 深入探讨Linux静态库与动态库的详解(一看就懂)  # 分析Windows和Linux动态库  # 在动态库和静态库中使用模板(dynamic libraries  # static libraries)  # 可执行  # 应用程序  # 可执行文件  # 这类  # 加载  # 这个时候  # 较小  # 时才  # 命名为  # 自己的  # 头文件  # 运行环境  # 是一种  # 好了  # 多个  # 分工合作  # 不需要  # 两种  # 会在  # 将其 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 大型企业网站制作流程,做网站需要注册公司吗?  高防服务器租用如何选择配置与防御等级?  Android自定义控件实现温度旋转按钮效果  详解MySQL数据库的安装与密码配置  历史网站制作软件,华为如何找回被删除的网站?  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  iOS验证手机号的正则表达式  linux top下的 minerd 木马清除方法  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践  EditPlus 正则表达式 实战(3)  如何在云主机快速搭建网站站点?  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  教你用AI润色文章,让你的文字表达更专业  Laravel怎么连接多个数据库_Laravel多数据库连接配置  Laravel如何实现用户密码重置功能?(完整流程代码)  海南网站制作公司有哪些,海口网是哪家的?  javascript基本数据类型及类型检测常用方法小结  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  简历没回改:利用AI润色让你的文字更专业  如何快速搭建自助建站会员专属系统?  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  如何实现javascript表单验证_正则表达式有哪些实用技巧  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  如何在景安云服务器上绑定域名并配置虚拟主机?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  Android okhttputils现在进度显示实例代码  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  实例解析angularjs的filter过滤器  制作公司内部网站有哪些,内网如何建网站?  Laravel如何处理表单验证?(Requests代码示例)  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  详解jQuery中基本的动画方法  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  Laravel如何实现一对一模型关联?(Eloquent示例)  百度浏览器如何管理插件 百度浏览器插件管理方法  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  5种Android数据存储方式汇总  Linux后台任务运行方法_nohup与&使用技巧【技巧】  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  Laravel如何配置和使用缓存?(Redis代码示例)  利用vue写todolist单页应用  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  如何生成腾讯云建站专用兑换码?