通常你们都用 JSPatch?前端
用别人的,总很差。老王造了个轮子,我来描述一下。git
怎么设计这个 Patch?github
Patch 主要是 干什么的呢? 通常大公司的 App 在运行的过程中,业务线很是复杂,可能会出现一些问题。后端
能够远端下发一个文件,开发的 App 经过 加载 这个文件, 实行 这个 代码 补丁。bash
OC 能够的,由于是动态语言,有 runtime ,因此才能搞这个 patch。app
OC 有本身的消息转发流程。 Runtime 有 objc_msgSend
和 _objc_msgForward
。 Runtime 有这两个方法, 这两个函数特性,让全部的函数调用都会走这两个方法。函数
这样 app 中有一个 context, 能够执行用于 patch 的语言。优化
本文中的 iOS 补丁方案直接运用 这个 JavaScriptCore, 就是使用 JavaScriptCore 提供的 JSContext. 能让 JavaScript 语言 和 Objective-C 之间,有一个接口。而后就能够 JavaScript 与 Objective-C 相互调用了。 ( JavaScriptCore, 固然是苹果本身实现的 )ui
FFI, Foreign Function Interface ,就是把一个语言暴露出来的接口,能让其余语言来调用。 Java 的 JNI 标准,与 FFI 比较类似。 FFI ,首先听从 Coding Convention ,就是定义遵照一些调用的协议和规定。 为何要有 FFI 呢?lua
咱们执行一个函数调用,首先开辟一个栈帧,这个栈帧传递一些什么样的参数?参数的类型是什么?参数 的个数,是多少?包括这个函数里面,执行的一些动做是什么? FFI 就把遵照的一些调用的协议和规定定义出来。
老王 Patch 库的这个自定义 FFI , 就是把想拉来打补丁的 patch 语言, 对接 Objective-C 的执行环境。 须要往里面传递的命令,把这个东西,给规定出来。
使用 JSPatch 的过程中,老王发现,用的很是的不顺手, 为何他不顺手呢? 老王觉得,JSPatch 把 JavaScript 硬生转换成至关于 Objective-C 这种风格的补丁代码。 其间作了不少的语言处理,包括 Bang 说的源函数的处理。 包括 C 语言函数,相似 Ruby 的 Method Mission . 至于其余, 老王觉得, JSPatch 都是在后端进行的。
要增强 Patch, 自己具备的语言的一个平滑性,就是写 JavaScript , 就使用 JavaScript 的写法
把 JavaScriptContext 的注册接口,抽象出三个层,
define, 往 Objective-C 发消息。 不须要参数返回, 能够用 define . 须要定义的,确定都本身定义的。 抽象出这一层,就能够了。
须要一个返回值的时候,使用 去执行一些什么任务
老王感受苹果封装的 JavaScriptContext,可能有一些问题。 好比说, 传递的一些函数对象,开发者封装了两层。那就可能获取不到这个对象了。 这个时候, 须要 Callback 方式,在那个执行环境当中,获取前端的 function 内容。 用 JavaScriptCore 相关的一种回调方式,来取到在当前 JavaScriptContext 环境 当中的一个 function 值。
这个 patch ,是干什么的? 对所使用的内容, 有哪些指令?
经过 这些指令,咱们能够实现, 想要 patch 到的一些功能
对于 Objective-C 中的 self 关键字, 一般用来表明当前对象的指针。 还须要改 super 关键字, 为 oc_super. 由于 super 在 ECMAScript 6 里面, 也是关键字了,须要回避掉。 original, 是 Patch 中特有的。调用以前的函数,即打补丁以前的这个函数的调用。
对 JavaScript 高阶函数作一个平滑处理,不然可能写起来,很是费劲。
a.request(
function(a:id,b:Int):double{},
callback:(string,string) => int,
(num1:string, num2:double) => { return num1 + num2; }
);
复制代码
request 方法, 有三个参数。三个 function 类型的参数。第一个 function 函数,接收两个参数。第二个参数 callback, 是咱们在函数调用上下文中取到的。第三个参数是, ECMAScript 6 中使用的箭头函数。 最好呢,对这个进行一些支持。 这些操做,是经过预处理的方式,编译成可以对接 OC 的 Block 指令的。
基本能够正常完成工做了。
你们都仿照 JSPatch,在 JavaScriptContext 中注册一大堆本身要进行 patch 的函数。 想要用到什么,就去补充什么。 通常都是彻底借鉴 Bang 的一些想法。
Github 官方 repo 连接:https://github.com/wangyunico/iOSPatchBackend
个人民间 repo , https://github.com/BoxDengJZ/lao_wang_patch