服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS创建与使用静态库

iOS创建与使用静态库

2021-01-14 18:12DDChina IOS

这篇文章主要为大家详细介绍了iOS创建与使用静态库的相关资料,感兴趣的小伙伴们可以参考一下

  在日常项目开发中,不论是为了两个公司项目上的业务交流还是为了减少项目的编译时间,有的时候我们会把项目中的私密内容打包成静态库,或者是把项目中变动较少一部分打包成静态库以便提高编译效率,那么下面我们就来学习一下"ios-静态库的创建与使用":

(一)ios静态库、动态库与framework静态库与动态库的区别

(1)什么是库?

库(library)直白一点说就是一段编译好的二进制代码,加上头文件就可以供别人使用;(例如: ios中objective-c编译下的.h和.m文件,打包静态库后会变为.h和.a文件);

(2)什么是静态库?

①静态库即静态链接库(例如: windows下的.lib、mac和linux下的.a);

②静态库在编译的时候会被直接拷贝一份,复制到目标程序里并且这段代码在目标程序里就不会在改变了,我猜这也是该库叫"静态库"的原因;

③静态库的利弊:

1)利: 静态库在编译完成之后,库文件实际上就没有作用了,目标程序没有外部依赖,直接就可以运行;

2)弊: 弊端静态库会使用目标程序的体积增大;

(3)什么是动态库?

①动态库即动态链接库(例如: windows下的.dll、mac下的.dylib、linux下的.so);

②与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用,等到程序运行时,动态库才会被真正加载进来;

③动态库的利弊:

1)利:不需要拷贝到目标程序中,不会影响目标程序的体积,而且同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库);同时,编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码;

2)弊:动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境;如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行;

(4)什么时候我们会用到库呢?

①某些代码片段需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件;

②对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 link 一下,不会浪费编译时间;

说明:上面提到库在使用的时候需要link,link 的方式有两种:静态和动态,于是便产生了静态库和动态库("攻城狮"的思维就是这么简单);

(5)ios framework?

①除了上面我们提到ios的.a和.dylib之外,mac os/ios 平台还可以使用 framework,framework实际上是一种打包方式,将库的二进制文件、头文件和有关的资源文件打包到一起,方便管理和分发;在 ios 8 之前,ios 平台不支持使用动态 framework,开发者可以使用的 framework 只有苹果自家的 uikit.framework,foundation.framework 等等;

②上面这种限制可能是出于安全的考虑,换一个角度讲,因为 ios 应用都是运行在沙盒当中,不同的程序之间不能共享代码,同时动态下载代码又是被苹果明令禁止的,没办法发挥出动态库的优势,实际上动态库也就没有存在的必要了;

③由于上面提到的限制,开发者想要在 ios 平台共享代码,唯一的选择就是打包成静态库 .a 文件,同时附上头文件;但是这样的打包方式不够方便,使用时也比较麻烦,大家还是希望共享代码都能能像 framework 一样,直接扔到工程里就可以用;

④终于在日思夜盼便迎来了ios对动态库的支持:ios 8/xcode 6 推出之后,ios 平台添加了动态库的支持,同时 xcode 6 也原生自带了 framework 支持(动态和静态都可以);

⑤但是说道这里博主要告诉一下大家,ios动态库且用且珍惜(小心应用审核被拒);

(二)切入主题"ios静态库的创建":

(1)我们先了解静态库文件的版本(四种):

①真机-debug版本;  ②真机-release版本  ③模拟器-debug版本  ④模拟器-release版本;

(2)debug(调试)版本特点:

①含完整的符号信息,以方便调试;  ②不会对代码进行优化;

(3)release(发布)版本特点:

①不会包含完整的符号信息;  ②执行代码是进行过优化的;  ③大小会比debug版本的略小  ④在执行速度方面,release版本会快一些;

所以我们一般开发中都打包release(发布)版本使用;

(4)再来了解一下iphone设备cpu的架构简介:

①模拟器:(4s~5: i386)    (5s~6splus: x86_64)

②真 机: (3gs~4s: armv7)  (5~5c: armv7s)     (5s~6splus: arm64)[说明: 静态库只要支持了armv7,就可以跑在armv7s的架构上];

(三)制作静态库-debug版本:

(1)创建cocoa touch static library,新建项目选择ios ->framework&library ->cocoa touch static library,如图1:

iOS创建与使用静态库

(2)点击next给工程命名如"library"点击next,xcode自动为我们创建了library.h/.m文件以及相对应的目录结构,如图2所示:

    iOS创建与使用静态库

(3)接下来我们在工程的.h和.m里面编写功能实现的代码(重在静态库的创建, 代码粗略请大家无视):

?
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
35
36
37
"library.h"
/** 十六进制转二进制 */
+ (nsstring *)getbinarybyhex:(nsstring *)hex;
 
"library.m"
+ (nsstring *)getbinarybyhex:(nsstring *)hex {
  nsmutabledictionary *hexdic = [[nsmutabledictionary alloc] init];
  
  hexdic = [[nsmutabledictionary alloc] initwithcapacity:16];
  [hexdic setobject:@"0000" forkey:@"0"];
  [hexdic setobject:@"0001" forkey:@"1"];
  [hexdic setobject:@"0010" forkey:@"2"];
  [hexdic setobject:@"0011" forkey:@"3"];
  [hexdic setobject:@"0100" forkey:@"4"];
  [hexdic setobject:@"0101" forkey:@"5"];
  [hexdic setobject:@"0110" forkey:@"6"];
  [hexdic setobject:@"0111" forkey:@"7"];
  [hexdic setobject:@"1000" forkey:@"8"];
  [hexdic setobject:@"1001" forkey:@"9"];
  [hexdic setobject:@"1010" forkey:@"a"];
  [hexdic setobject:@"1011" forkey:@"b"];
  [hexdic setobject:@"1100" forkey:@"c"];
  [hexdic setobject:@"1101" forkey:@"d"];
  [hexdic setobject:@"1110" forkey:@"e"];
  [hexdic setobject:@"1111" forkey:@"f"];
  
  nsstring *binarystring=[[nsmutablestring alloc] init];
  
  for (int i=0; i<[hex length]; i++) {
    nsrange rage;
    rage.length = 1;
    rage.location = i;
    nsstring *key = [hex substringwithrange:rage];
    binarystring = [nsstring stringwithformat:@"%@%@",binarystring,[nsstring stringwithformat:@"%@",[hexdic objectforkey:key]]];
  }
  return binarystring;
}

(4)编译项目生成对应的静态库.a文件(在这里注意一下细节):

①在工程编译(command+b)之前"标号为②的框框中liblibrary.a"为红色(编译之后为黑色, 红色表示一个虚拟的文件工程中找不到它),如图3所示:

      iOS创建与使用静态库

②编译的过程中我们要选择"模拟器编译"和"真机编译",如图4图5所示:

      iOS创建与使用静态库

iOS创建与使用静态库

(5)右击工程目录下.a文件,查看编译之后的静态库文件如图6所示, 其中文件debug-iphoneos里面包含iphone真机所需要的liblibrary.a静态库文件,文件debug-iphonesimulator里面包含的时iphone模拟器所需要的liblibrary.a静态库文件,如图7所示;

    iOS创建与使用静态库

iOS创建与使用静态库

(6)分别查看打包好的模拟器与真机的静态库所支持的cpu架构:

在上面我们介绍了iphone设备cpu的架构,在这里我们就来查看我们所打包的静态库是否符合iphone设备包含的架构标准(提示: 如果不符合某些架构的标准,静态库运行到不同机型上回报错误),打开终端查看静态库的架构如图8所示:

iOS创建与使用静态库

我们找到原因如图9所示,下面debug:yes表示只编译选中模拟器对应的架构,no则为编译所有模拟器支持的cup架构(debug的yes状态改为no即可);

    iOS创建与使用静态库

再一次command+b 编译重复上面第(4)步的小步骤,就ok了,...

(7)合并静态库:

①为什么要合并静态库呢?

因为真机和模拟器的静态库,是不一样的,不能同时适用在真机和模拟器上,但要满足这要求的话,要对编译好的两个静态库进行合并在使用;

②合并静态库的利弊?

1)利:开发过程中既可以在真机上调试,也可以在模拟器上调试;

2)弊:如果静态库太大,合并打包后,会非常大,因此很多第三方的静态库的.a是区分版本的;

③打开终端合并静态库(终于快成功了...)如图10所示:

      iOS创建与使用静态库

其中完整的命令是:

复制代码 代码如下:
lipo -create /users/apple/library/developer/xcode/deriveddata/library-bmlhmlslupltsqfkcfgmgqzducdy/build/products/debug-iphoneos/liblibrary.a /users/apple/library/developer/xcode/deriveddata/library-bmlhmlslupltsqfkcfgmgqzducdy/build/products/debug-iphonesimulator/liblibrary.a -output /users/apple/desktop/liblibrary.a;

 

(8)静态库的使用:

将合并好的静态库文件(.a)和头文件(.h)添加到工程里面,调用静态库,结果如下(代码粗略请大家无视...):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"viewcontroller.h"
@interface viewcontroller : uiviewcontroller
 
@end
 
"viewcontroller.m"
#import "viewcontroller.h"
#import "library.h"
 
@interface viewcontroller ()
 
@end
 
@implementation viewcontroller
 
- (void)viewdidload {
  [super viewdidload];
  // 十六进制转二进制
  nslog(@"十六进制转二进制: %@", [library getbinarybyhex:@"f"]);
}

日志打印输入结果是:
静态库的使用[1006:40288] 十六进制转二进制: 1111

(四)制作静态库-release版本:

跟debug版步骤一样,只不过在编译时,改下面的选项即可如图12所示:

  iOS创建与使用静态库

这时不管是真机还是模拟器都可以编译通过,正常运行;而使用者只能通过头文件知道我们提供的借口,却不知道实现文件中实现的细节,这有效地隐藏了自己的核心技术和机密内容;

以上就是我对ios静态库的理解与解释,希望大家相互补充相互学习。

延伸 · 阅读

精彩推荐
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17