作者:蒲哟独CrRz | 来源:互联网 | 2023-09-25 09:07
最近在自己封装openssl库的基础上做开发,但是发现与现有的一些模块依赖的静态库有冲突,最后使用封装动态库(framework)解决了这一问题,现将学到的知识记录下来。
简介:
-
动态库形式:.dylib和.framework
-
静态库形式:.a和.framework
-
framework为什么既是静态库又是动态库?
-
系统的.framework是动态库,我们自己建立的.framework一般都是静态库。但是现在用xcode创建Framework的时候默认是动态库,一般打包成SDK给别人用的话都使用的是静态库,可以修改Build Settings的Mach-O Type为Static Library。
-
什么是framework
-
Framework是Cocoa/Cocoa Touch程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件、说明文档等集中在一起,方便开发者使用。一般如果是静态Framework的话,资源打包进Framework是读取不了的。静态Framework和.a文件都是编译进可执行文件里面的。只有动态Framework能在.app下面的Framework文件夹下看到,并读取.framework里的资源文件。
Cocoa/Cocoa Touch开发框架本身提供了大量的Framework,比如Foundation.framework/UIKit.framework/AppKit.framework等。需要注意的是,这些framework无一例外都是动态库。
平时我们用的第三方SDK的framework都是静态库,真正的动态库是上不了AppStore的(iOS8之后能上AppStore,因为有个App Extension,需要动态库支持)。
-
动态库和静态库的区别
-
下图中的绿色框表示可执行文件:
-
静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝(左图所示);
-
系统动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存(右图所示)
-
动态库的作用
-
应用插件化:
-
让每一个功能点都是一个动态库,在用户想使用某个功能的时候让其从网络下载,然后手动加载动态库,实现功能的的插件化
虽然技术上来说这种动态更新是可行的,但是对于AppStore上上架的app是不可以的。iOS8之后虽然可以上传含有动态库的app,但是苹果不仅需要你动态库和app的签名一致,而且苹果会在你上架的时候再经过一次AppStore的签名。所以你想在线更新动态库,首先你得有苹果APPStore私钥,而这个基本不可能。
共享可执行文件:
-
在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,iOS仍然不允许进程间共享动态库,即iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。
不过iOS8上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。
-
如果我们创建的framework是动态库,那么我们直接在工程里使用的时候会报错:Reason: Image Not Found。需要在工程的General里的Embedded Binaries添加这个动态库才能使用。
-
我们创建的动态库和系统的动态库有什么区别呢?我们创建的动态库是在我们自己应用的.app目录里面,只能自己的App Extension和APP使用。而系统的动态库是在系统目录里面,所有的程序都能使用。
-
因为我们创建的这个动态库其实也不能给其他程序使用的,而你的App Extension和APP之间是需要使用这个动态库的。这个动态库可以App Extension和APP之间共用一份(App 和 Extension 的 Bundle 是共享的),因此苹果又把这种 Framework 称为 Embedded Framework,而我把这个动态库称为伪动态库。
-
下图表示了静态库,自己创建的动态库和系统动态库:
参考:iOS里的动态库和静态库(http://www.cocoachina.com/cms/wap.php?action=article&id=25511)