一、动态链接库与静态链接库的区别 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 1. 静态函数库 这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。 2. 动态函数库 这类库的名字一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。 二、使用库的优势 使用静态库的好处 1,模块化,分工合作 2,避免少量改动经常导致大量的重复编译连接 3,也可以重用,注意不是共享使用
动态库使用有如下好处: 1使用动态库,可以将最终可执行文件体积缩小 2使用动态库,多个应用程序共享内存中得同一份库文件,节省资源 3使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。 三、iPhone对于链接库的支持 iPhone官方只支持静态库联编,不支持动态链接库。而对于静态库有两种方式:一种是生成.a文件;一种是生成静态framework。所谓的静态framework,实际上也是一种静态库,其相对于.a文件来说,区别在于其不仅包含了库文件,还包含了头文件和资源文件。而在使用.a文件时,还要另外添加.h文件。 iPhone不支持动态链接库的原因可能有: ①共享给谁?(因为在现在的iPhone,iPodTouch,iPad上面程序都是单进程的,也就是某一时刻只有一个进程在运行,你使用的时候只有你一个应用程序存在,其他的应该被挂起了,即便是可以同时多个进程运行,别人能使用你的共享库里的东西吗?你这个是给你自己的程序定制的。) ②目前苹果的AppStore不支持模块更新,无法更新某个单独文件(除非自己写一个更新机制:有自己的服务端放置最新动态库文件),也就是说,就算你通过其他方式产生了动态链接库,也无法达到更新动态库文件从而更新应用程序的目的。 四、Xcode对于创建库的支持 Xcode不支持自己创建动态链接库。而framework也分为静态框架和动态框架,大部分框架都是动态链接库的形式。因为只有苹果才能在iOS设备上安装动态库,所以我们也无法创建动态框架。 而且苹果也从Xcode中移除了创建静态iOS框架的功能!!! 通常来说,Xcode只支持创建静态库文件.a。但是实际上Appstore是允许代码封装在静态链接库中的。所以,出现了所谓的”伪框架”和”真框架”。 五、框架的类别和使用 前面说了,框架分为静态框架和动态框架,对于静态框架,在生成过程中又有了”真”、”伪”的区别。 1、”伪”框架 “伪”框架是破解的“reloacatable object file”(可重定位格式的目标文件, 保存着代码和数据,适合于和其他的目标文件连接到一起,用来创建一个可执行目标文件或者是一个可共享目标文件),它可以让Xcode编译出类似框架的东西——其本质是一个bundle。 “伪框架”模板把整个过程分为几个步骤,用某些脚本去产生一个真正的静态框架(基于静态库而不是reloacatable object file)。而且,框架项目还是把它定义为wrapper.cfbundle类型,一种Xcode中的“二等公民”。 因此它跟“真”静态框架一样可以正常工作,但当存在依赖关系时就有麻烦了。 依赖问题 如果不使用依赖,只是创建普通的项目是没有任何问题的。但是如果使用了项目依赖(比如在workspace中),Xcode就悲剧了。当你点击“Link Binary With Libraries”下方的’+’按钮时,“伪框架”无法显示在列表中。你可以从你的“伪”框架项目的Products下面将它手动拖入,但当你编辑你的主项目时,会出现警告: warning: skipping file '/somewhere/MyFramework.framework' (unexpectedfile type 'wrapper.cfbundle' in Frameworks & Libraries build phase) 并伴随“伪”框架中的链接错误。 幸运的是,有个办法来解决它。你可以在”Other Linker Flags”中用”-framwork”开关手动告诉linker去使用你的框架进行链接: -framework MyFramework 警告仍然存在,但起码能正确链接了。 2、”真”框架 “真”框架各个方面都符合“真”的标准。它是真正的静态框架,正如使用苹果在从Xcode中去除的那个功能所创建的一样。 为了能创建真正的静态框架项目,你必需在Xcode中安装一个xcspec文件。 如果你发布一个“真”框架项目(而不是编译),希望去编译这个框架的人必需也安装xcspec文件(使用本次发布的安装脚本),以便Xcode能理解目标类型。 注意:如果你正在发布完全编译的框架,而不是框架项目,最终用户并不需要安装任何东西 3、不同框架类型的使用时机 简单来说,你可以这样决定用哪一种框架: · 如果你不想修改Xcode,那么请使用“伪”框架版本 · 如果你只是想共享二进制(不是项目),两种都可以 · 如果你想把框架共享给不想修改Xcode的开发者,使用“伪”框架版本 · 如果你想把框架共享给修改过Xcode的开发者,使用“真”框架版本 · 如果你想把框架项目作为另一个项目的依赖(通过workspace或者子项目的方式),请使用“真”框架(或者“伪”框架,使用-framework——见后) · 如果你想在你的框架项目中加入其他静态库/框架,并把它们也链接到最终结果以便不需要单独添加到用户项目中,使用“伪”框架 六、IOS静态框架的创建、编译和使用 1、安装框架模板 要想在xcode中创建静态框架,须得先安装相应的模板iOS Universal Framework Mk iOS Universal Framework Mk 8的下载地址:https://github.com/kstenerud/iOS-Universal-Framework 解压下载文件,打开Terminal,进入到刚下载文件,Fake Framework下面。输入命令:sh install.sh。同理安装Real Framework下的文件。安装完毕如下图: 分别运行Real Framework目录或Fake Framework目录下的install.sh脚本进行安装(或者两个你都运行)。 重启Xcode,你将在新项目向导的Framework&Library下看到StaticiOS Framework(或者Fake Static iOS Framework)。 若要卸载这两个模板,请运行unistall.sh脚本并重启Xcode。 2、 创建一个IOS框架项目 ①创建新项目。 ②项目类型选择Framework&Library下的Static iOS Framework(或者Fake Static iOS Framework)。 ③ 选择“包含单元测试”(可选的)。 ④在target中加入类、资源等。 ⑤凡是其他项目要使用的头文件,必需声明为public。进入target的Build Phases页,展开Copy Headers项,把需要public的头文件从Project或Private部分拖拽到Public部分。 3、 编译IOS框架、 ① 选择指定target的scheme。 ②修改scheme的Run配置(可选)。Run配置默认使用Debug,但在准备部署的时候你可能想使用Release。 ③编译框架(无论目标为iOS device和Simulator都会编译出相同的二进制,因此选谁都无所谓了)。 ④从Products下选中你的framework,“show in Finder”。 在build目录下有两个文件夹:(yourframework).framework and (your framework).embeddedframework. 如果你的框架只有代码,没有资源(比如图片、脚本、xib、coredata的momd文件等),你可以把(yourframework).framework 分发给你的用户就行了。如果还包含有资源,你必需分发(your framework).embeddedframework给你的用户。 为什么需要embedded framework?因为Xcode不会查找静态框架中的资源,如果你分发(your framework).framework, 则框架中的所有资源都不会显示,也不可用。 一个embedded framework只是一个framework之外的附加的包,包括了这个框架的所有资源的符号链接。这样做的目的是让Xcode能够找到这些资源 4、 使用静态框架 iOS框架和常规的Mac OS动态框架差不多,只是它是静态链接的而已。 在你的项目中使用一个框架,只需把它拖仅你的项目中。在包含头文件时,记住使用尖括号而不是双引号括住框架名称。例如,对于框架MyFramework: #import <MyFramework/MyClass.h> 七、静态库.a文件的编写 IOS产生.a的静态库,比起.framework相对简单了好些。 下面介绍一下具体生成步骤: 1、新建一个framework&library库。IOS 下的cocoa touch static library。然后输入product name 为libsql
2、把libsql.h和libsql.m删除。导入ocsqlite.h和ocsqlite.c(文件见http://blog.csdn.net/fengsh998/article/details/8278978) 3、修改scheme,设为release版本。
OK,选译ios device编译运行。成功后将在目录的build/products/release-iphoneos/下产生一个liblibsql.a文件。 注,这里产生的是真机使用的.a文件。 选译iphonesimulator 进行编译一次,同样会在build/products/release-iphonesimulator/下产生一个liblibsql.a文件。 这里是虚拟机使用的.a文件。
下面来看一下这两个文件有什么不同之处,使用lipo -info命令。 打开终端。 进入到相应的目录。 真机的:liblibsql.a文件信息。 input file liblibsql.a is not a fat file Non-fat file: liblibsql.a is architecture: armv7 如图: 模拟器的:liblibsql.a文件信息。 input file liblibsql.a is not a fat file Non-fat file: liblibsql.a is architecture: i386 如图: 如果使用真机和模拟器通用,则需要将这两个文件合并,使用命令lipo -create xxxx/liblibsql.a xxxxx/liblibsql.a -output libsql.a 同样可以使用lipo -info 来查看这个合并的libsql.a 可以看到architectures in the fat file: libsql.a are: i386 armv7 如图: 八、iOS中创建,使用动态库(dylib) 由于苹果不支持自己创建动态库,所以这里需要替换两个文件 ①iOS Device 需要替换的文件 替换路径:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/ ②iOS 模拟器需要替换的文件 替换路径:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications 具体可参照:http://blog./?p=33 或者 http://www./bbs/simple/?t129814.html 替换完成后重启Xcode。 创建动态库
1:打开Xcode,新建项目,选择OS X --> Cocoa Library -->输入动态库的相关信息
2:这样,动态库已经创建好,但是由于此项目是基于Mac OS X创建的,所以这里要将project的相关设置作修改
1:Base 设置成 SDK iOS6.0
2:Architectures 设置成 standrand (armv7 armv7s)
3:Installation Directory 设置成 @executable_path/
4:Mach-O Type 设置成 Dynamic Library
5:Executable Prefix 设置成 空
6:打开项目的project.pbxproj(文本编辑器打开)文件,在编辑器中将producttype 的值修改为 com.apple.product-type.library.dynamic
7:选择合适的证书文件
3:将debug改为no
4:在动态库的相关类中添加一些测试方法 5:删除多余的framework文件。值添加Foundation.framework文件
Xcode--->Preferences--->Locations--->Advanced---->
这样基本就可以编译dylib了,但是这里还有一个需要注意的地方。 编译证书的选择
编译分为设备编译(iOS Device)及模拟器编译(iPad/iPhone Simulator) 在选择设备编译的时候,一定要选择某个有效的开发者证书。否则编译会出错。 相反,选择模拟器编译的时候,不需要选择证书(如果选了证书,也会报错)。
如果一切正常,那么在编译后的文件会出现在项目文件夹的Build/Products/.…文件夹中
参考文档:1、http://blog.csdn.net/stackhero/article/details/9032999关于静态库、动态库的区别汇总 2、http://blog.csdn.net/stackhero/article/details/9032891 iOS中创建,使用动态库(dylib) 3、http://blog.csdn.net/fengsh998/article/details/8291965 IOS 4.2 编写通用的静态库.a文件 |
|