iOS开发动态库加载实时模块更新.docx
《iOS开发动态库加载实时模块更新.docx》由会员分享,可在线阅读,更多相关《iOS开发动态库加载实时模块更新.docx(7页珍藏版)》请在冰豆网上搜索。
iOS开发动态库加载实时模块更新
iOS开发-动态库加载(实时模块更新)
iOS开发-动态库加载(实时模块更新)
作者
NiePlus
2016.03.2215:
10*
字数1429
阅读2405评论11喜欢14动态库和静态库
静态库和动态库是相对编译期和运行期:
静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间需要动态库的存在。
静态库的好处
模块化,分工合作,提高了代码的复用及核心技术的保密程度;避免少量改动经常导致大量的重复编译链接;也可以重用,注意不是专享使用。
动态库的好处
可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,将进行分工,影响比较小;
多个应用程序共享内存中得同一份库文件,节省资源;可以不重新编译链接可执行文件程序的前提下,更新动态库文件达到更新应用程序的目的;应用插件化。
软件版本实时模块升级
共享执行可执行文件,在其他大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。
从目前来看,iOS仍然不允许进程间共享动态库,己iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以为的其他任何地方。
不过iOS8上开发了App
Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可以行的。
动态库和主工程的创建
本文章只针对动态库创建,软件版本实时模块升级进行说明,静态库不做详细解释说明。
动态库创建
创建工程类型为Framework&Library下的CocoaTouchFramework工程,工程命名DynamicLink;创建继承UIViewController命名为ViewController的控制器,设置背景颜色;//动态库视图颜色
self.view.backgroundColor=[UIColorgreenColor];
创建继承NSObject命名为DynamicOpenMenth文件,在DynamicOpenMenth.h中
//动态链对外开发方法
-(void)startWithObject:
(id)objectwithBundle:
(NSBundle*)bundle;
在DynamicOpenMenth.m中方法实现
-(void)startWithObject:
(id)objectwithBundle:
(NSBundle*)bundle
{
//初始化第一个controller
//这里的重点是资源文件的加载,通常我们在初始化的时候并不是很在意bundle:
这个参数,
//其实我们所用到的图片、xib等资源文件都是在程序内部中获取的,也就是我们常用的[NSBundlemainBundle]中获取,所谓的NSBundle本质上就是一个路径,mainBundle指向的是.app下。
//而如果我们不指定bundle,则会默认从.app路径下去寻找资源。
//不过很显然,我们的动态库是放到“主程序”的document文件下的,所以资源文件是不可能在[NSbundlemainBundle]中获取到的,所以这里我们需要指定bundle参数,这也是传递framework的路径的意义所在
ViewController*vc=[[ViewControlleralloc]init];
vc.root_bundle=bundle;
//转换传递过来的mainCon参数,实现界面跳转
UIViewController*viewCon=(UIViewController*)object;
[viewConpresentViewController:
vcanimated:
YEScompletion:
^{
NSLog(@"跳转到动态更新模块成功!
");
}];
}
在BuildOnlyDevice下编译程序,生成DynamicLink.Framework文件,文件可在工程目录下Products文件夹下ShowInFinder中找到;
主工程创建
创建SingleViewApplication的工程,命名为DynamicLibrary。
在ViewController.m中实现以下方法
-(void)touchesBegan:
(NSSetUITouch*>*)toucheswithEvent:
(UIEvent*)event
{
//动态库测试
[selfperformSelector:
@selector(dynamicLibraryClick)withObject:
nil];
}
-(void)dynamicLibraryClick
{
//document路径
NSArray*paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*documentDirectory=nil;
if([pathscount]!
=0)
documentDirectory=[pathsobjectAtIndex:
0];
NSLog(@"\nDocuments路径=%@\n",documentDirectory);
//拼接我们放到document中的framework路径
NSString*libName=@"DynamicLink.framework";
NSString*destLibPath=[documentDirectorystringByAppendingPathComponent:
libName];
//判断一下有没有这个文件的存在 如果没有直接跳出
NSFileManager*manager=[NSFileManagerdefaultManager];
if(!
[managerfileExistsAtPath:
destLibPath]){
NSLog(@"Thereisn'thavethefile");
return;
}
//复制到程序中
NSError*error=nil;
//加载方式二:
使用NSBundle加载动态库
NSBundle*frameworkBundle=[NSBundlebundleWithPath:
destLibPath];
if(frameworkBundle){
NSLog(@"bundleloadframeworksuccess.");
}else{
NSLog(@"bundleloadframeworkerr:
%@",error);
return;
}
//通过NSClassFromString方式读取类,FrameWorkStart为动态库中入口类
ClasspacteraClass=NSClassFromString(@"DynamicOpenMenth");
if(!
pacteraClass){
NSLog(@"UnabletogetTestDylibclass");
return;
}
//1.初始化方式采用下面的形式,alloc init的形式是行不通的,同样,直接使用PacteraFramework类初始化也是不正确的
//2.通过-(id)performSelector:
(SEL)aSelectorwithObject:
(id)object1withObject:
(id)object2;
//3.方法调用入口方法(startWithObject:
withBundle:
),并传递参数(withObject:
selfwithObject:
frameworkBundle)
NSObject*pacteraObject=[pacteraClassnew];
[pacteraObjectperformSelector:
@selector(startWithObject:
withBundle:
)withObject:
selfwithObject:
frameworkBundle];
}
将动态库生成的DynamicLibrary.Framework动态库文件导入到主工程运行下的Documents文件下;
注意:
模拟器运行下,直接讲DynamicLibrary.Framework动态库文件拖拽到打印出的文件夹中即可,真机运行需打开iTunes倒入到DynamicLibrary应用中。
以上为动态库加载主要实现,存在一些的问题需要感兴趣的朋友一起讨论,比如ClasspacteraClass=NSClassFromString(@"DynamicOpenMenth");读取类的时候为什么值为nil等。
目前可以肯定动态库达不到更新效果!
了解到JSPatch,可以实时修复iOS线上问题。
但JSPatch也有个缺点,不能实现大规模功能模块更新。
技术交流群:
193996724
推广iOS开发-Git命令的简单操作:
本文Demo下载地址:
作者:
NiePlusiOS开发-Object-C
?
著作权归作者所有
举报文章
NiePlus
写了18195字,被386人关注,获得了257个喜欢
不经一番寒彻骨,怎得梅花扑鼻香!
面对工作压力,生活压力,社会压力学习iOS的迷茫之路...
如果觉得我的文章对您有用,请随意打赏。
您的支持将鼓励我继续创作!
分享到QQ空间
分享到Twitter
分享到Facebook
分享到Google+
分享到豆瓣
"data-original-title=""title="">更多分享
后发表评论11条评论只看作者按喜欢排序按时间正序按时间倒序593e27d363792楼·2016.03.2217:
18受教了赞回复NiePlus:
@593e27d36379存在一些问题,ClasspacteraClass=NSClassFromString(@"DynamicOpenMenth");这个方法,读取类时候为什么值一直为nil?
可以试下。
2016.03.2217:
32回复瑞小萌:
@NiePlus确实,这个做法是有问题的2016.03.3011:
10回复NiePlus:
@瑞小萌document中倒入工程中的动态库可以加载到,重新编译的动态库倒入到documents文件夹中就不行,iOS实现插件方式更新还是指日可待。
2016.03.3014:
39回复添加新评论
还有3条评论,
展开查看饼哥阿杜3楼·2016.09.2717:
43“目前可以肯定动态库达不到更新效果!
”,我验证了下模拟器。
可以加载document下的动态库,更新后的重启就可以加载到。
不确定通过网络的方式重新下载动态库资源包后,重启是否生效。
赞回复肚子总是饿4楼·2017.02.2220:
48转载也不注明出处哦赞回复NiePlus:
@肚子总是饿没转载啊2017.02.2301:
11回复小四:
真机无法run,直接crash。
。
。
2017.03.0410:
49回复