iOS中的库

目录:

1. 库是什么?
2. 静态库与动态库的区别
3. 使用库
4. iOS系统中的库

库是什么?

下面这张图大家一定很熟悉,这是windows上经常见到的一幕,我们可能刚刚安装完一个软件或者某个大型游戏,满心欢喜的准备启动时,蹦出这个东西:


这个就是库引起问题,具体我们下面会进行分析。那么库是什么?
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。通俗地讲,库就是一个组件,一般是可以复用的组件,这样每个需要这个组件的程序都可以使用这个组件,如果组件的代码内联在程序中,则失去组件的意义。

开发中为了实现快速迭代,我们通常要避免造轮子:首先自己造的轮子问题多,其次造轮子时间长。 所以我们通常会考虑开源库。
开源库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。使用开源库首先必须了解代码所遵循的协议,常见的协议如gpl bsd mit等,分清各种协议需要承担的责任,例如我们使用的这份代码的头文件中描述了协议:


其他开源库都相应github页面上都会描述遵循的协议。
大家如果留意iOS系统中可以享用的开源库,会发现作为一个iOS开发者的幸福:大量有用高质量的开源库,并且使用相对宽松的多的协议,可以让开发者使用的同时不用太关注侵权和付费问题,而大家如果使用大型的开源库时,比如音视频处理的ffmpeg,会发现这个库使用了严苛的协议,开发者使用时就要关注是否修改源码?修改后如果负责?使用了如何收费?是否侵权等诸多问题。
我想这也是iOS开发者为何这样如泉涌一般出现,因为这样一个开放、相对自由又低门槛的环境让许多新人有一个更快进入、更熟练进阶的学习曲线。
协议参考:
http://blog.csdn.net/nightmare/article/details/12405109
http://www.cnblogs.com/Wayou/p/how_to_choose_a_license.html

静态库与动态库的区别
库按照链接的方式可以分为两种,静态库和动态库。

静态库

【静态库】是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。静态库的代码在编译链接后已经被载入可执行程序,因此体积较大。静态库的“静态”是指编译链接后库已经固定在可执行文件中,如果需要更新库中内容,需要重新编译链接,才能在可执行程序中生效,对程序的更新、部署和发布页会带来麻烦。

静态库可以看成是一堆对象.o文件(object files)的归档,所以静态库可以通过ar -x xxxx.a 来分解出其中的所有.o文件。当链接这样一个库到应用中时,static linker将会从库中收集这些对象.o文件并把它们和应用的对象代码一起打包到一个二进制文件中。这意味着应用的可执行文件大小将会随着库的数目增加而增长。另外,当应用启动时,应用的代码(包含库的代码)将会一次性地导入到程序的地址空间中去。

参考下图:

app加载静态库

动态库

【动态库】在程序编译时并不会被链接到目标代码中,如下图可见,可执行文件中只是保存动态库各个api的引用,保留着相对地址,在程序运行时,等可执行程序中使用动态库的某个api时,动态库会载入到内存某个区域(非当前可执行文件所在内存块),可执行程序所在进程将会生成这个动态库的空间映射,从而被进程调用。

由此可见,动态库是直到程序启动时被需要时才加载到内存(增加了启动时间,如果需要运行时再加载,需要处理),app启动时,系统在内核态完成一些必要配置,从App的MachO文件解析出dyld的地址启动dyld,然后通过dyld加载依赖的动态库。 并且,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题(目前在iOS系统上不会这样,因为iOS系统的沙盒机制禁用了进程之间的动态库共享)。动态库在程序启动时才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,可以实现增量更新。

app加载动态库

iOS中的dylib支持上述形式,但其他动态库不支持。
windows系统支持上图形式:dll动态库,
自己开发的程序可以加载系统的dll,这样程序的大小变得很小。对于开篇windows上碰到的弹窗问题,其实问题就在动态库的致命弱点上:由于一个系统中的不同软件如果是基于同于dll的不同版本,不同版本dll之间的接口或内部逻辑又有所差异就会造成系统中某个软件可以用,其他就不可以用,但同一时刻系统又只保留一个dll,所以无法保证这些软件都能正常使用。

这也体现了windows和iOS两个系统对动态库的宽容性,前者对每个系统版本中dll的兼容性做的不好,并且允许用户自己生成的dll文件,而后者兼容做的好的多,apple这方面为了避免出现这个情况,在iOS8之前是不允许用户自定义的动态库出现的,提交到appstore的应用不能包含动态库,但是iOS8之后apple开放了这个限制,用户可以在app中使用动态库。 但是apple 审核中注明了,不允许动态下发代码,所以通过更换app中的动态库实现增量更新是行不通的(每个app提交后都是经过签名的,如果app使用了动态库,也会同时签名,在app校验签名通过才能运行,如果直接替换动态库,签名这关过不了。对于不发布到appstore的应用可以参考这里通过framework动态更新)。我们常用的第三方库管理工具carthage打包的framework就是动态库。

mac中区分两种库
那么我们平时如何知道使用的库是动态库还是静态库呢?最简单的方式就是mac电脑上的finder可以识别两种库,如下图:


动态库
静态库

从上图可以看出,动态库在finder中的预览图跟其他可执行文件一样是exec形式,而静态库没有对应预览图。

这里还有个问题,上面我们已经分析到,动态库中不会直接将外部引用链接进去,所以对于较大的工程一般静态库都比动态库小很多,但是上图例子中我没有添加任何源码的情况下,空的动态库比静态库大不少,用sublime打开发现动态库中很大部分都是00, 这是怎么回事有待求证。

使用库

上面提到了动态库比静态库好的方面,那么我们在项目中应该怎么取舍?直接用动态库吗?
这里需要注意,动态库虽然文件小,占据空间小,但是我们在app中使用时由于与可执行文件是独立放在ipa中,因为在运行时在加载到内存中,所以xcode工程配置(如下图)需要将二进制文件嵌入进去,这样实际上我们生成的app的大小比使用静态库会大。

xcode配置使用动态库

如果是静态库,这步可以省略。
所以实际项目中可以根据需求判断,是想要运行时启动时加载库少,占用内存少,启动快? 还是app安装文件小(过大会被appstore限制,后期可能影响其他需求的添加)?

我们一般何时需要使用第三方库:

  1. 需要轮子
    开发中,有一个重要原则:D R Y 对应着 don‘t repeat yourself
    也就是说我们要避免重复的代码,不仅是自己重复的代码要做好重构和复用,也避免写一些别人已经写好的代码,用好第三方库。
  2. 协同开发
    以一个大型工程为例:
    如果一个大型工程可能包含消息 空间 voip电话 公众号 圈子 等很多功能模块时,这些模块都属于不同小团队负责,这个大工程需要加载所有这些模块,需要编译迅速,主线版本稳定,通常都要各个模块需要独立工程管理,主工程通过加载各个子工程的静态库来编译运行,这样每个小模块的开发人员只需要关注自己模块内部的工程,编译速度快,整个团队的效率高。
  3. 共享代码或者以库为产品
    就像我们使用他人的源码或库一样,我们也可以把自己积累的比较通用的源码分享出去,让其他人集成来提高开发进度,或者将我们的源码编译成库,商业运作形式变卖。这时我们就需要确定自己的协议,也就是说别说使用我们的源码或库需要履行哪些责任,怎么付费等
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容