转载《Xcode 创建静态库和动态库》

Xcode 创建静态库和动态库

地址链接   http://www.cocoachina.com/ios/20150921/13385.html

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路径


1

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添加新的脚本来实现模拟器和真机合并:

脚本如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

# 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文件夹中,使用如下代码动态使用动态库:


1

2

3

4

5

6

7

8

9

#import NSString *documentsPath = [NSString stringWithFormat:@"%@/Documents/DymicLib.framework/DymicLib",NSHomeDirectory()];

void * libHandle = NULL;

libHandle = dlopen([documentsPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW);

if (libHandle == NULL) {

    char *error = dlerror();

    NSLog(@"dlopen error: %s", error);

else {

    NSLog(@"dlopen load framework success.");

}

使用  动态库 中的类:


1

2

3

4

5

Class rootClass = NSClassFromString(@"DymicLog");

if (rootClass) {

    id object = [[rootClass alloc] init];

    [(DymicLog *)object relog:@"hello world"];

}

时间: 2024-10-31 12:41:55

转载《Xcode 创建静态库和动态库》的相关文章

【转载】C++拷贝构造函数(深拷贝,浅拷贝)

对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. #include <iostream>using namespace std;class CExample {private:     int a;public:     CExample(int b)     { a=b;}     void Show ()     {        cout<

门控时钟-理论分析 ---- 转载

转载自:http://www.chipsbank.com/news_detail/newsId=123.html 门控的基本要求: 1. 所需要的沿(对于正沿触发的寄存器是正沿,对于负沿触发的寄存器是负沿)不增加,不减少: 1. 不会产生毛刺: 1. 使用后功耗要能够降低: 1. 最好面积还会减小. 1. 上升沿触发的门控时钟的结构研究:应用与上升沿触发的寄存器的门控. 1. 直接与门结构: 1. 高电平使能Latch + 与门结构: 1. 低电平使能Latch + 与门结构: 1. 波形研究:

浅谈Java中的equals和==(转载)

在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 4 System.out.println(str1==str2); 5 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一样?==和equals方法之间的区别是什么?如果在初学Java的时候这个问题不弄清楚,就

JVM学习(2)——技术文章里常说的堆,栈,堆栈到底是什么,从os的角度总结--转载http://www.cnblogs.com/kubixuesheng/p/5202561.html

转载自---http://www.cnblogs.com/kubixuesheng/p/5202561.html 俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及到的知识点总结如下: 堆栈是栈 JVM栈和本地方法栈划分 Java中的堆,栈和c/c++中的堆,栈 数据结构层面的堆,栈 os层面的堆,栈 JVM的堆,栈和os如何对应 为啥方法的调用需要栈 属于月经问题了,正好碰上有人问我这类比较基础的知识,无奈我自觉回答不是有效果,现在深入浅出的总结下: 前一篇文章总结了:JV

GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git分支 标签 过滤 Git版本工作流(转载)

最近听同事说他都在使用GitHub,GitHub是程序员的社区,在里面可以学到很多书上学不到的东西,所以最近在准备入手这方面的知识去尝试学习,正好碰到这么详细完整的文章,就转载了,希望对自己和大家有帮助. GitHub操作总结 : 总结看不明白就看下面的详细讲解. GitHub操作流程 : 第一次提交 : 方案一 : 本地创建项目根目录, 然后与远程GitHub关联, 之后的操作一样; -- 初始化Git仓库 :git init ; -- 提交改变到缓存 :git commit -m 'desc

2.EasyUI学习总结(二)——easyloader分析与使用(转载)

本文转载自:http://www.cnblogs.com/haogj/archive/2013/04/22/3036685.html 使用脚本库总要加载一大堆的样式表和脚本文件,在easyui 中,除了可以使用通常的方式加载之外,还提供了使用 easyloader 加载的方式.这个组件主要是为了按需加载组件而诞生.什么情况下使用它呢? 你觉得一次性导入 easyui 的核心 min js 和 css 太大 你只用到 easyui 的其中几个组件 你想使用其中的一个组件,但是你又不知道这个组件依赖

Data guard概念篇一(转载)

本文转载至以下链接,感谢作者分享! http://tech.it168.com/db/2008-02-14/200802141545840_1.shtml 一.Data Guard配置(Data Guard Configurations) Data Guard是一个集合,由一个primary数据库(生产数据库)及一个或多个standby数据库(最多9个)组成.组成Data Guard的数据库通过Oracle Net连接,并且有可能分布于不同地域.只要各库之间可以相互通信,它们的物理位置并没有什么

【转载】GBDT(MART) 迭代决策树入门教程 | 简介

      转载地址:http://blog.csdn.net/w28971023/article/details/8240756        GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree),是一种迭代的决策树算法,该算法由多棵决策树组成,所有树的结论累加起来做最终答案.它在被提出之初就和SVM一起被认为是泛化能力(generalization)较强的算法.近些年更因为被用于搜索排

LIB和DLL的区别与使用(转载)

转载自:http://www.cppblog.com/amazon/archive/2009/09/04/95318.html 共有两种库:一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library.一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library.共有两种链接方式:动态链接使用动态链接库,允许可执行模块(.dll文件或.e

[转载]HDFS初探之旅

转载自 http://www.cnblogs.com/xia520pi/archive/2012/05/28/2520813.html , 感谢虾皮工作室这一系列精彩的文章. Hadoop集群(第8期)_HDFS初探之旅 1.HDFS简介 HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上.它所具有的高容错.高可靠性.高可扩展性.高