前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >能让 JS 执行的 JavascriptCore ,到底是啥

能让 JS 执行的 JavascriptCore ,到底是啥

作者头像
前端修罗场
发布2022-07-29 08:34:34
1.4K0
发布2022-07-29 08:34:34
举报
文章被收录于专栏:Web 技术

在这篇文章中我们知道,ISO 版微信小程序逻辑层中的 JavaScript 代码运行在 JavaScriptCore 中,那么 JavascriptCore 到底有什么神奇的地方,能让 JS 在 IOS 中执行呢?

Swift 自 2014 年推出以来,人气飙升,但是 JavaScript 是一种与 Swift 完全相反的语言,比如 Swift 在编译时做了很多保障安全性的措施,而 JavaScript 则是一门弱类型语言,它只在执行时运行。可能它们两个也没想到有一天能够一起协作,制作一个流畅的 iOS 应用程序! 但是,你知道为什么 JS 能在 IOS 中运行吗?本篇文章,我们就来说说能让 JS 在 IOS 运行的 JavascriptCore 框架到底是什么。你将了解到以下知识点:

  • JavaScriptCore 框架的组成。
  • 如何从 iOS/Swift 代码中调用 JavaScript 。
  • 如何从 JavaScript 访问 IOS/Swift 代码。

开始

JavaScriptCore 框架提供对 WebKit 的 JavaScript 引擎的访问。最初,该框架有一个仅限 Mac 的 C API,但 iOS 7 和 OS X 10.9 附带了一个更好的 Objective-C 包装器。该框架能够使你的 Swift/Objective-C 和 JavaScript 代码之间具有强大的操作性。

在底层,JavaScriptCore 由几个关键组件组成:JSVirtualMachine、JSContext 和 JSValue。那它们是如何组合在一起的呢?往下看。

JSVirtualMachine:JS 虚拟机

JavaScript 代码在由 JSVirtualMachine 类表示的虚拟机中执行。你通常不必直接与此类交互,但它有一个主要作用:能够支持 JavaScript 并发执行。由于在单个 JSVirtualMachine 中,不可能同时执行多个线程。因此,为了支持并行性,必须使用多个虚拟机。 JSVirtualMachine 的每个实例都有自己的堆和垃圾收集器,这意味着你不能在虚拟机之间传递对象。因为,如果你那样做的话,虚拟机的垃圾收集器会不知道如何处理来自不同堆的值。

JSContext

JSContext 对象代表 JavaScript 代码的执行环境。 它对应于单个全局对象它如同 Web 开发中的 window 对象。与虚拟机不同,你可以在上下文之间自由传递对象(假设它们位于同一虚拟机中)。

JSValue

JSValue 是你必须使用的主要数据类型:它可以表示任何可能的 JavaScript 值JSValue 的实例与它所在的 JSContext 对象相关联来自上下文对象的任何值都将是 JSValue 类型。 下图显示了上述每个部分之间是如何协同工作的:

image.png

现在你对 JavaScriptCore 框架中已经有了初步的了解。接下来,我们来看看 IOS 代码与 JS 代码之间是如何调用的。

在 IOS 中调用 JS 代码

在 IOS 中要调用 JS,首先要在 swift 文件顶部引入 JavaScriptCore 包:

代码语言:javascript
复制
import JavaScriptCore

接着,你可以在 Swift 代码中创建一个 JSContext 对象,使用这个对象的 evaluateScript 方法,可以执行一段 JS 代码:

代码语言:javascript
复制
let context = JSContext()
JSValue *value = context.evaluateScript(params); // 参数以字符串形式传入

通过 evaluateScript 执行的 JS 代码将会得到一个 JSValue 类型的值。

在 JS 中调用 ISO 代码

这部分应该是前端工程师比较关注的。

默认情况下,Swift/Oc 类的任何方法或属性都不会暴露给 JavaScript。相反,必须选择要导出的方法和属性。对于类遵循的每个协议,如果该协议包含 JSExport 协议,JavaScriptCore 会将该协议解释为要导出到 JavaScript 的方法和属性的列表。 那 JSExport 协议是什么呢?

JSExport是JavaScriptCore框架里的一个协议。如果一个协议遵守了JSExport,那么该协议的方法会对JS开放,允许JS直接调用)。JS Export 协议可以将你的 Swift 类及其实例方法、类方法和属性导出到 JavaScript 代码。

实际的原理是,当你在 Swift/Oc 代码中导出需要的属性时,JavascriptCore 框架会在原型上创建一个 Javascript 可访问属性。如果你导出的是一个类的方法时,JavascriptCore 框架则会在构造函数上创建一个 Javascript 函数。

如下代码所示,显示了 JS 调用 OC/Swift 代码的过程:

代码语言:javascript
复制
@protocol MyPointExports <JSExport>
@property double x; // @property 声明的属性决定了 JavaScript 中相应的属性的可读、枚举情况
@property double y;
(MyPoint *)makePointWithX:(double)x y:(double)y;
@end

@interface MyPoint : NSObject <MyPointExports>

@end

@implementation MyPoint
// ...
@end

在 JS 中可以这样调用上面的 OC/Swift 代码:

代码语言:javascript
复制
// 使用构造函数语法调用 OC 初始化程序
var p = MyPoint(, );
// OC 类方法成为构造函数对象上的函数
var q = MyPoint.makePointWithXY(, );

在实际开发中,JS 与 IOS 工程师需要确定好调用的方法名称(假设为 jsToOc);其次,ISO 工程师需要在 JSContext 中注册 OCJSBridge 对象为 [OCJSBridge new]。此时,OCJSBridge.jsToOc 便是在 JS 需要调用到的。一旦在 JS 调用了,IOS 中的 jsToOc 方法就会响应 JS 的调用请求,并解析随方法携带过来的参数。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端修罗场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开始
  • JSVirtualMachine:JS 虚拟机
  • JSContext
  • JSValue
  • 在 IOS 中调用 JS 代码
  • 在 JS 中调用 ISO 代码
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档