原理

JSPatch用iOS内置的JavaScriptCore.framework作为JS引擎,但没有用它JSExport的特性进行JS-OC函 数互调,而是通过Objective-C Runtime,从JS传递要调用的类名函数名到Objective-C,再使用NSInvocation动态调用对应的OC方法。详细的实现原理以及实 现过程中遇到的各种坑和hack方法会另有文章介绍。

方案对比

目前已经有一些方案可以实现动态打补丁,例如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,但使用时参数上也有比较多的限制。

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

风险

JSPatch让脚本语言获得调用所有原生OC方法的能力,不像web前端把能力局限在浏览器,使用上会有一些安全风险:

1.若在网络传输过程中下发明文JS,可能会被中间人篡改JS脚本,执行任意方法,盗取APP里的相关信息。可以对传输过程进行加密,或用直接使用https解决。

2.若下载完后的JS保存在本地没有加密,在未越狱的机器上用户也可以手动替换或篡改脚本。这点危害没有第一点大,因为操作者是手机拥有者,不存在APP内相关信息被盗用的风险。若要避免用户修改代码影响APP运行,可以选择简单的加密存储。

其他用途

JSPatch可以动态打补丁,自由修改APP里的代码,理论上还可以完全用JSPatch实现一个业务模块,甚至整个APP,跟wax一样,但不推荐这么做,因为:

  1. JSPatch和wax一样都是通过Objective-C
    Runtime的接口通过字符串反射找到对应的类和方法进行调用,这中间的字符串处理会损耗一定的性能,另外两种语言间的类型转换也有性能损耗,若用来做
    一个完整的业务模块,大量的频繁来回互调,可能有性能问题。
  2. 开发过程中需要用OC的思维写JS/Lua,丧失了脚本语言自己的特性。
  3. JSPatch和wax都没有IDE支持,开发效率低。

若想动态为APP添加模块,目前React Native给出了很好的方案,解决了上述三个问题:

  1. JS/OC不会频繁通信,会在事件触发时批量传递,提高效率。(详见React Native通信机制详解
  2. 开发过程无需考虑OC的感受,遵从React框架的思想进行纯JS开发就行,剩下的事情React Native帮你处理好了。
  3. React Native连IDE都准备好了。

所以动态添加业务模块目前还是推荐尝试React Native,但React
Native并不会提供原生OC接口的反射调用和方法替换,无法做到修改原生代码,JSPatch以小巧的引擎补足这个缺口,配合React
Native用统一的JS语言让一个原生APP时刻处于可扩展可修改的状态。

JSPatch 原理的更多相关文章

  1. JSPatch 实现原理详解

    原文地址https://github.com/bang590/JSPatch/wiki/JSPatch-%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E8%AF%A6%E8 ...

  2. JSPatch常见问题解答

    原文地址:https://github.com/bang590/JSPatch/wiki/JSPatch%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7 ...

  3. iOS 中的 HotFix 方案总结详解

    相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Ap ...

  4. 有关iOS热更新

    iOS热更新的几篇文章,看完这几篇,自己集成一下.下面说一下我集成时遇到的问题. 这是原作者的JSPatch的讲解的文章:<JSPatch – 动态更新iOS APP>.<JSPat ...

  5. IOS热更新-JSPatch实现原理+Patch现场恢复

    关于HotfixPatch 在IOS开发领域,由于Apple严格的审核标准和低效率,IOS应用的发版速度极慢,稍微大型的app发版基本上都在一个月以上,所以代码热更新(HotfixPatch)对于IO ...

  6. JSPatch实现原理详解<二>

    本文转载至 http://blog.cnbang.net/tech/2855/ 距离上次写的<JSPatch实现原理详解>有一个月的时间,在这段时间里 JSPatch 在不断地完善和改进, ...

  7. JSPatch实现原理详解

    本文转载至 http://blog.cnbang.net/tech/2808/ JSPatch以小巧的体积做到了让JS调用/替换任意OC方法,让iOS APP具备热更新的能力,在实现 JSPatch ...

  8. 【腾讯Bugly干货分享】JSPatch 成长之路

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/579efa7083355a9a57a1ac5b Dev Club 是一个交流移动 ...

  9. JSPatch使用小记

    hotfix的作用众所周知,Android和iOS都有各自的技术,但是相比Android的当天发布来说(如果你们的项目不需要灰度),iOS热更新的意义更加重大.因为iOS审核周期长不说,而且运气不好会 ...

随机推荐

  1. C++快速开发样本工程的建立--简介

    背景 在开发项目过程中,一些功能库能反复被写被用,可以写成库被重用: 但是行业业务也随着换项目,每次重新写一次,如果把一些功能业务和框架绑定,配置绑定,只需要添加,修改,增加业务功能,就可以搭建C++ ...

  2. C#调整图片亮度和对比度

    BitmapSource bitmap = null; ; ; private void SetBrightness(int degree) { degree = degree * / ; Write ...

  3. python+soket实现UDP协议的局域网广播程序

    # udp_gb_server.py '''服务端(UDP协议局域网广播)''' import socket s = socket.socket(socket.AF_INET, socket.SOCK ...

  4. [Qt扒手2] PyQt5 路径绘画例子

    [说明] 此例扒自 Qt 官网,原例是 C++ 代码,我把它改写成了 Python + PyQt5 版本. 有了前一个例子的成功,这个例子改写的非常之快.记得第一个例子花了我几天的时间,而这个例子只花 ...

  5. python面试题(三)

    一.项目技术点梳理 (一)Django项目 本项目是用python的Django框架开发的前后端不分离项目.项目采用MVT架构,使用的MySQL和redis数据库,用Django自带的orm与数据库交 ...

  6. async/await工作机制探究--NodeJS

    ES6中的async/await让Promise变得更加简便,通常await处理的链式Promise会包裹在函数中,返回结果仍然是一个Promise对象. 但是当await直接处理链式Promise时 ...

  7. 网易公开课[一万分钟]《office办公达人养成计划》

    note: Shift表示移动 Ctrl表示复制 Excel: 快速选中单元格: 选中表格左上角Ctrl+A Ctrl+方向键,跳到行或列的尽头 Ctrl+Shift+方向键,选中一行或一列 Shif ...

  8. 解决Unity烘焙阴影锯齿精度不足的问题

    烘焙阴影锯齿问题  烘焙后阴影锯齿明显,如下图: 烘焙的光照贴图质量主要受LightmapParameters 的Blur Radius和抗锯齿级别影响, 默认最高级别如下: 如果最高级别不能达到好的 ...

  9. SICP读书笔记 3.3

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  10. Docker容器的启动与停止

    启动docker:systemctl start docker 停止docker:systemctl stop docker 重启docker:systemctl restart docker 查看d ...