Hummer 中 JS 与 OC的通信原理

273 阅读1分钟

前言

Hummer 是滴滴开源的跨端框架,目前是货运司机端的重要开发框架,以下对其通信原理做简要说明

(其实它并不是 JS 和 OC 之间通信)

原理

  • JSObjectMakeFunctionWithCallback :使 JS 代码能够调用 C 函数。具体例子见Hummer SDK 中的 hummerCall 函数(搜一下就出来了)

    JSObjectMakeFunctionWithCallbackApple文档,创建一个 JS 可以调用函数,它有三个参数:

    1. ctx:JS 执行上下文(类似 JSContext,但是它是更底层的JSContextRef类型,C 语言)

    2. name:函数名称

    3. callAsFunction:函数实现,JSObjectCallAsFunctionCallback类型。

    但是 Hummer 不是直接把"hummerCall"这个字符串传进去的,而是把传了一个 NULL 的name ,返回**得到了一个****JSObjectRef**对象。有效的绑定还得看下面这个👇🏻

JSObjectRef inlineHummerCallFunction = JSObjectMakeFunctionWithCallback(_contextRef, NULL, &hummerCall);
  • JSObjectSetProperty:给JS全局对象设置属性(可以把上述绑定的 C 函数设置成 JS 对象的一个属性)

    该函数是给对象设置属性。接受6个参数:

    1. ctx:同上
    2. object:要设置的对象
    3. propertyName:要设置的属性名
    4. value:属性的值
    5. attributes:属性的特性,比如 kJSPropertyAttributeReadOnly(只读),kJSPropertyAttributeDontDelete(无法删除)
    6. exception:异常抛出
JSObjectSetProperty(_contextRef, globalThis, hummerCallString, inlineHummerCallFunction, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, &exception);

我猜这么写就是为了把这个函数跟globalThis关联起来

  • globalThis的类型 —— JSContextGetGlobalObject:JS 执行上下文中的全局对象

至此,JS 侧已经可以调用 hummerCall 方法了,如下:

// Hummer/iOS/builtin/src/injectClassModel.ts, 该文件可以在 Humemr 源码文件夹下找到
return globalThis.hummerCall(this._private, jsClassName, methodPropertyModel.nameString, ...args)

参考资料