framework是Cocoa/Cocoa Touch程序中使用的一种资源打包方式,可以将将代码文件、头文件、资源文件、说明文档等集中在一起,方便开发者使用,作为一名Cocoa/Cocoa Touch程序员每天都要跟各种各样的Framework打交道。Cocoa/Cocoa Touch开发框架本身提供了大量的Framework,比如Foundation.framework/UIKit.framework/AppKit.framework等。需要注意的是,这些framework无一例外都是动态库。
但残忍的是,Cocoa Touch上并不允许我们使用自己创建的framework。不过由于framework是一种优秀的资源打包方式,拥有无穷智慧的程序员们便想出了以framework的形式打包静态库的招数,因此我们平时看到的第三方发布的framework无一例外都是静态库,真正的动态库是上不了AppStore的。
WWDC2014给我的一个很大感触是苹果对iOS的开放态度:允许使用动态库、允许第三方键盘、App Extension等等,这些在之前是想都不敢想的事。
iOS动态库可以做什么呢
和静态库在编译时和app代码链接并打进同一个二进制包中不同,动态库可以在运行时手动加载,这样就可以做很多事情,比如:
应用插件化
目前很多应用功能越做越多,软件显得越来越臃肿。因此插件化就成了很多软件发展的必经之路。软件版本实时模块升级
还在忍受苹果动辄一周,甚至更长的审核周期吗?有了动态库妈妈就再也不用担心你的软件升级了!
如果软件中的某个功能点出现了严重的bug,或者想在其中新增功能,你的这个功能点又是通过动态库实现的,这时候你只需要在适当的时候从服务器上将新版本的动态库文件下载到本地,然后在用户重启应用的时候即可实现新功能的展现。共享可执行文件
在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,iOS仍然不允许进程间共享动态库,即iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。
不过iOS8上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。
PS: 上述关于动态库在iOS平台的使用,在技术上都是可行的,但本人并没有真正尝试过做出一个上线AppStore的应用,因此并不保证按照上述方式使用动态库一定能通过苹果审核!
2014-6-23修正:
经@唐巧_boy提醒,sandbox会验证动态库的签名,所以如果是动态从服务器更新的动态库,应该是签名不了的,因此应用插件化、软件版本实时模块升级估计很难实现,一切都只能等到iOS8正式版发布以后再验证了。感谢@唐巧_boy!
创建动态库
1、创建动态库
创建工程文件
在下图所示界面能够找到Cocoa Touch动态库的创建入口:
跟随指引一步步操作即可创建一个新的动态库工程,我的工程名字叫Dylib,Xcode会同时创建一个和工程target同名的.h文件,比如我的就是Dylib.h。
向工程中添加文件
接下来就可以在工程中随意添加文件了。我在其中新建了一个名为Person的测试类,提供的接口如下:
对应的实现部分:
Dylib.h中要添加引用:”Person.h”
设置开放的头文件
一个库里面可以后很多的代码,但是我们需要设置能够提供给外界使用的接口,可以通过Target—>Build Phases—>Headers来设置,如下图所示:
我们只需将希望开放的头文件放到Public列表中即可,比如我开放了Dylib.h和Person.h两个头文件,在生成的framework的Header目录下就可以看到这两个头文件,如下图所示:
一切完成,Run以后就能成功生成framework文件了。
2、通用动态库
经过第一步我们只是创建了一个动态库文件,但是和静态库类似,该动态库并同时不支持真机和模拟器,可以通过以下步骤创建通用动态库:
- 创建Shell Script
按提示一步步操作即可,我给Aggregate的Target的命名是CommonDylib。
设置Target Dependencies
按以下路径设置CommonDylib对应的Target Dependencies:
TARGETS–>Build Phases–>Target Dependencies
将真正的动态库Dylib Target添加到其中。添加Run Script
在CommonDylib.sh添加Run Script:
这段脚本的作用是:
1.分别编译生成真机和模拟器使用的framework;
2.使用lipo命令将其合并成一个通用framework;
3.最后将生成的通用framework放置在工程根目录下新建的Products目录下。
如果一切顺利,对CommonDylib target执行run操作以后就能生成一个如图所示的通用framework文件了:
使用动态库
- 添加动态库到工程文件
经过以上步骤的努力,生成了最终需要的framework文件,为了演示动态库的使用,新建了一个名为FrameworkDemo的工程。并将刚生成的framework添加到工程中:
仅仅这样做是不够的,还需要为动态库添加链接依赖
自动链接动态库
添加完动态库后,如果希望动态库在软件启动时自动链接,可以通过以下方式设置动态库依赖路径:
其中的@executable_path/表示可执行文件所在路径,即沙盒中的.app目录,注意不要漏掉最后的/。
如果你将动态库放到了沙盒中的其他目录,只需要添加对应路径的依赖就可以了。需要的时候链接动态库
动态库的另一个重要特性就是即插即用性,我们可以选择在需要的时候再加载动态库。
1.更改设置:
或者更干脆的,将Dylib.framework从Link Binary With Libraries列表中删除即可。
2.使用NSBundle加载动态库
通过上述任一一种方式加载的动态库后,就可以使用动态库中的代码文件了!
监测动态库的加载和移除
我们可以通过下述方式,为动态库的加载和移除添加监听回调:
基本思路转自:http://blog.csdn.net/yongyinmg/article/details/41513917