iOS热更新-JSPatch实现原理+Patch现场恢复

关于HotfixPatch

在iOS开发领域,由于Apple严格的审核标准和低效率,iOS应用的发版速度极慢,稍微大型的app发版基本上都在一个月以上,所以代码热更新(HotfixPatch)对于iOS应用来说就显得尤其重要。

现在业内基本上都在使用WaxPatch方案,由于Wax框架已经停止维护四五年了,所以waxPatch在使用过程中还是存在不少坑(比如参数转化过程中的问题,如果继承类没有实例化修改继承类的方法无效, wax_gc中对oc中instance的持有延迟释放...)。另外苹果对于Wax使用的态度也处于模糊状态,这也是一个潜在的使用风险。

随着FaceBook开源React Native框架,利用JavaScriptCore.framework直接建立JavaScript(JS)和Objective-C(OC)之间的bridge成为可能,JSPatch也在这个时候应运而生。最开始是从唐巧的微信公众号推送上了解到,开始还以为是在React Native的基础上进行的封装,不过最近仔细研究了源代码,跟React Native半毛钱关系都没有,这里先对JSPatch的作者(不是唐巧,是Bang,博客地址)赞一个。

深入了解JSPatch之后,第一感觉是这个方案小巧,易懂,维护成本低,直接通过OC代码去调用runtime的API,作为一个IOS开发者,很快就能看明白,不用花大精力去了解学习lua。另外在建立JS和OC的Bridge时,作者很巧妙的利用JS和OC两种语言的消息转发机制做了很优雅的实现,稍显不足的是JSPatch只能支持ios7及以上。

由于现在公司的部分应用还在支持ios6,完全取代Wax也不现实,但是一些新上应用已经直接开始支持ios7。个人觉得ios6和ios7的界面风格差别较大,相信应用最低支持版本会很快升级到ios7. 还考虑到JSPatch的成熟度不够,所以决定把JSPatch和WaxPatch结合在一起,相互补充进行使用。下面给大家说一些学习使用体会。

JSPatch和WaxPatch对比

关于JSPatch对比WaxPatch的优势,下面摘抄一下JSPatch作者的话:

方案对比

目前已经有一些方案可以实现动态打补丁,例如WaxPatch,可以用Lua调用OC方法,相对于WaxPatch,JSPatch的优势:

  • 1.JS语言: JS比Lua在应用开发领域有更广泛的应用,目前前端开发和终端开发有融合的趋势,作为扩展的脚本语言,JS是不二之选。

  • 2.符合Apple规则: JSPatch更符合Apple的规则。iOS Developer Program License Agreement里3.3.2提到不可动态下发可执行代码,但通过苹果JavaScriptCore.framework或WebKit执行的代码除外,JS正是通过JavaScriptCore.framework执行的。

  • 3.小巧: 使用系统内置的JavaScriptCore.framework,无需内嵌脚本引擎,体积小巧。

  • 4.支持block: wax在几年前就停止了开发和维护,不支持Objective-C里block跟Lua程序的互传,虽然一些第三方已经实现block,但使用时参数上也有比较多的限制。

JSPatch的劣势:

  • 相对于WaxPatch,JSPatch劣势在于不支持iOS6,因为需要引入JavaScriptCore.framework。另外目前内存的使用上会高于wax,持续改进中。

JSPatch的实现原理理解

JSPatch的实现原理作者的博文已经很详细的介绍了,我这里就不多说了,贴一下学习之处:

看实现原理详解的时候对照着源码看,比较好理解,我在这里说一下我对JSPatch的学习和理解:

(1)OC的动态语言特性

不管是WaxPatch框架还是JSPatch的方案,其根本原理都是利用OC的动态语言特性去动态修改类的方法实现。
OC的动态语言特性是在runtime system(全部用C实现,Apple维护了一份开源代码)上实现的,面向对象的Class和instance机制都是基于消息机制。我们平时认为的[object method],正确的理解应该是[receiver sendMsg], 所有的消息发送会在编译阶段编译为runtime c函数的调用:_obj_sendMsg(id, SEL).

详细介绍参考博文:

runtime提供了一些运行时的API

  • 反射类和选择器
    Class class = NSClassFromString("UIViewController");
    SEL selector = NSSelectorFromString("viewDidLoad");
  • 为某个类新增或者替换方法选择器(SEL)的实现(IMP)
    BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值