IOS 静态库和动态库

本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举原文出处还望见谅与指出,另文章内容如有不妥之处还望指教,万分感谢!

什么是库 ?

库就是程序代码的集合,将N个文件组织起来,是共享程序代码的一种方式。库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。

库的分类

\bullet 开源库:源代码是公开的,可以看到每个实现文件(.m)的实现,例如GitHub上的常用的开源库:AFNetworking、SDWebImage等;

\bullet 闭源库:不公开源代码,是经过编译后的二进制文件,看不到基础题的实现。闭源库又分为:静态库和动态库

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

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

静态库:

命名方式:这类库的名字一般是libxxx.a

缺点:利用静态函数库编译成的文件比较大,因为整个函数库所有的数据都会被整合进目标代码中。

优点:编译后的执行程序不需要外部的函数库支持,因为所有使用的函数已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

动态库:

命名方式:这类库的名字一般是libxxx.so

缺点:程序执行到相关函数时才进行调用,程序运行环境中必须提供相应的库 ,而且因为不是预先加载所以在链接函数的时候需要做大量的工作。

优点:动态库在编译的时候,并没有被编译近目标代码,你的程序执行到相关函数是才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。动态函数库的改变并不影响程勋,所以动态函数库的升级比较方便。

2. IOS 开发中静态库和动态库的区别:

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

静态库 好处:

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

    \bullet 避免少量改动导致大量的重复编译连接,可以重用,注意不是共享使用

动态库 好处:

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

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

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

    \bullet 应用插件化

    \bullet 软件版本实时模块升级

    \bullet 在其他大部分平台上,动态库都可以用于不同应用间共享,共享可执行文件,这就大大节省了内存。

    iOS平台在iOS8之前,苹果不允许第三方框架使用动态方式加载,从iOS8开始允许开发者有条件的创建    和使用动态框架,这种框架叫做Cocoa Touch Framework.虽然同样是动态框架,但是和系统framework不    同,app中使用Cocoa Touch Framework 制作的动态库,在打包和提交app时会被放到app main bundle 的    跟目录中,运行在沙盒里,而不是系统中。也就是说,不同的APP就算使用了同样的framework,但还是会    有多份的框架被分别签名、打包、加载。不过iOS8上开放了App Extension功能,可以为一个应用创建插    件,这样主app和插件之间共享动态库还是可行的。

    iOS系统专属的framework是共享的(如 UIKit),但是而我们自己使用Cocoa Touch Framework 制作的动态库是放到app bundle中,运行在沙盒中的。

静态库和动态库的存在的形式

    \bullet 静态库:以 .a 和 .framework 为文件后缀名。

    \bullet 动态库:以.tbd(之前叫.dylib)和framework为文件后缀名。(系统直接提供给我们的framework都是动态库)

    \bullet 理解: .a是一个纯二进制文件,.framework中出了有二进制文件之外还有资源文件。.a 要有.h文件以及资源文件配合使用;.framework文件可以直接使用。总得来说,.a + .h +sourceFlie = .framework .所以创建静态库最好还是用.framework的形式创建。

静态库和动态库的区别

不同点:

    \bullet 静态库在链接时会被完整的复制到可执行文件中,如果多个App都使用了同一个静态库,那么每个App都会拷贝一份,缺点是浪费内存空间。类似于定义一个基本变量,使用该基本变量时新复制一份数据,而不是原来定义的;

    \bullet 动态库不会复制,只有一份,程序运行时动态加载到内存中,系统只会加载一次,多个程序共用一份,节约内存。类似于使用变量的内存地址一样,使用的是同一个变量;

共同点:

    \bullet 静态库和动态库都是闭源库,只能拿开满足某个功能的使用,不会暴露内部具体的代码信息。

静态库的处理方式

对于一个静态库而言,其实已经是编译好的了,类似一个 .o 的集合 这里并没有链接。在 build 的过程中只会参与链接的过程,而这个链接的过程简单的讲就是合并;并且连接器只会将静态库中被使用的部分合并到可执行文件中去。相对较于动态库,静态库的处理起来要简单的多,具体如下图:

    \bullet 链接器会将所有***.o***用到的global symbol 和unresolved symbol 放在一个临时表,而且是global symbol 是不能重复的。

    \bullet 对于静态库的 .o 链接器会将没有任何symbol在unresolved symbol table的给忽略。

    \bullet unresolved symbol 类似 extern int test() ;  .h 文件的声明 

    \bullet global symbol 类似 void test() { }  .m文件实现 

   \bullet 最后,链接器会用函数的实际地址来代替函数引用。

动态库的处理方式

首先,对于动态库而言其实分:动态链接库和动态加载库两种,这两种最本质的区别还是加载时机。

        \bullet 动态链接库: 在没有被加载到内存的前提下,当可执行文件被加载,动态库也随着被加载到内存中。在linked framework and Libraries 设置的一些share libraries 【随着程序启动而启动】

       \bullet 动态加载库:当需要的时候再使用 dlopen 等通过代码或者命令的方式来加载。【在程序启动之后】

\oplus  但是不论是那种动态库,相比较于静态库,动态库处理起来要棘手的多。由于动态库是动态的,所以你事先不知道某个函数的具体地址。因此动态连接器在链接函数的时候需要做大量的工作。

因为动态库在链接函数需要做大量的工作,而静态库已经事先处理好了。所以单纯的再所有都没有加载的情况下,静态库的加载速度会更快一点。虽然动态库更加耗时,但是对于加载过share libraries 不需要再加载的这个前提下,使用动态库可以节省一些启动时间。

   \oplus  而实现这个动态链接是使用了 Procedure Linkage Table (PLT).首先这个PLT列出了程序中每个函数的调用,当程序开始运行,如果动态库被加载到内存中,PLT会去寻找动态的地址记录下来,如果每个函数都被调用过的话,下一次调用就可以通过PLT直接跳转了,但是和静态库还是有点区别的是,每一个函数的调用还是需要通过一张PLT。这也是sunny所说的所有经验链接做的事情都搬到运行时来做了,会导致更慢的原因。

从源代码到app

当我们点击了 build 之后,做了什么事情呢?

\bullet 预处理(Pre-process):把宏替换,删除注释,展开头文件,产生 .i 文件。

\bullet 编译(Compliling):把之前的 .i 文件转换成汇编语言,产生 .s文件。

\bullet 汇编(Asembly):把汇编语言文件转换为机器码文件,产生 .o 文件。

\bullet 链接(Link):对.o文件中的对于其他的库的引用的地方进行引用,生成最后的可执行文件(同时也包括多个 .o 文件进行 link)。

动态库动态更新问题

能否动态库的方式来动态更新AppStore上的版本呢?

    framework本来是苹果专属的内部提供的动态库文件格式,但是自从2014年WWDC之后,开发者也可以自定义创建framework实现动态更新(绕过apple store审核,从服务器发布更新版本)的功能,这与苹果限定的上架的app必须经过apple store的审核制度是冲突的,所以含有自定义的framework的app是无法在商店上架的,但是如果开发的是企业内部应用,就可以考虑尝试使用动态更新技术来将多个独立的app或者功能模块集成在一个app上面!(我开发的就是企业内部使用的app,我们将企业官网中的板块开发成4个独立的app,然后将其改造为framework文件最终集成在一款平台级的app当中进行使用,这样就可以在一款app上面使用原本4个app的全部功能!)

    使用自定义的动态库的方式来动态更新只能用在 in house(企业发布) 和develop 模式却但不能在使用到 AppStore 因为在上传打包的时候,苹果会对我们的代码进行一次 Code Singing,包括 app 可执行文件和所有Embedded 的动态库。因此,只要你修改了某个动态库的代码,并重新签名,那么 MD5 的哈希值就会不一样,在加载动态库的时候,苹果会检验这个 hash 值,当苹果监测到这个动态库非法时,就会造成 Crash.

iOS 如何使用 framework 来进行动态更新!

重要参考文档(一定要看):

iOS 利用 Framework 进行动态更新

谈谈 Mach-O

Mach-O

    \bullet 在制作 framework 的时候需要选择这个 Mach-O Type.

    \bullet 为Mach Object文件格式的缩写,它是一种用于可执行文件,目标代码,动态库,内核转储的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性,并提升了符号表中信息的访问速度。

参考链接: https://www.cnblogs.com/junhuawang/p/7598236.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容