JSPatch

官方原理:https://github.com/bang590/JSPatch/wiki/JSPatch-实现原理详解

jspatch是依靠字符串反射,实现的动态更新。

1.require
require 做的就是在JS全局作用域上创建一个同名变量,变量指向一个对象,对象属性 __clsName 保存类名,同时表明这个对象是一个 OC Class。

var _require = function(clsName) {
  if (!global[clsName]) {
    global[clsName] = {
      __clsName: clsName
    }
  }
  return global[clsName]
}

所以,在写的js中,若发现对象拥有__clsName属性,则表明这是一个oc类

2.JS接口
js中的类调用不存在的方法会马上崩溃,so,利用了如下类似于消息转发
js代码在被oc执行之前,会先将内容用正则匹配替换,规则如:
UIView.alloc().init() -> UIView.__c('alloc')().__c('init')()
这样,js的所有方法调用都到了__c方法之中,而这个方法被添加到了js基类Object中,

Object.defineProperty(Object.prototype, '__c', {value: function(methodName) {
  if (!this.__obj && !this.__clsName) return this[methodName].bind(this);
  var self = this
  return function(){
    var args = Array.prototype.slice.call(arguments)
    return _methodFunc(self.__obj, self.__clsName, methodName, args, self.__isSuper)
  }
}})

_methodFunc方法就是调用oc原生方法,并且返回对象给js端

3。对象持有/转换
如var view = UIView.alloc()返回给js的是一个oc指针,但是js并不能分辨是一个oc指针还是一个js对象。变量view调用方法时候,怎么能知道是oc指针还是js对象调用方法?
jspatch统一对oc返回给js的对象用_wrapObj进行包装,包装对象具有__obj属性,属性值为oc对象指针。这样,方法调用时候,转发到__c中,在这里面判断对象是否具有__obj属性,就能分辨是否为oc对象,从而执行oc原生方法

4.方法替换
js执行的方法最终都是通过_methodFunc执行的oc原生方法,通过方法交换覆盖oc代码中原来的方法,通过动态绑定为oc添加属性。

jspatch被禁,苹果的解释是因为安全隐患。感觉jspatch太过强大,利用字符串反射能够做的事情oc绝大部分事情,可能苹果怕怕。。
安全方面主要是布丁下发传输过程中的问题,采用https或者rsa加密可以解决。
比如:电脑A生成rsa公钥public_key和私钥private_key,补丁包main.js下发时利用private_key加密得到private_main.js,发送文件为main.js以及private_main.js,app收到补丁包利用public_key解密private_main.js得到解密后的public_main.js,跟得到的main.js比较,相同即可用。否则main.js被篡改。

jspatch平台主要就是做了上面的事儿,同时有灰度,回滚,异常上报等。
回滚:值得是当用户得到补丁包,但是应用打开多次崩溃时候,应该能够禁止执行补丁的回滚功能。

你可能感兴趣的:(JSPatch)