使用 JavaScriptCore 进行跨语言调用

使用 JavaScriptCore 进行跨语言调用时,既可以在 Native 代码中执行 JavaScript 代码,也可以在 JavaScript 中调用 Native 方法。以下是详细的实现步骤和示例。

1. 在 Native 代码中执行 JavaScript 代码

使用 JavaScriptCore 框架,可以在 Swift 或 Objective-C 代码中执行 JavaScript 代码,并获取执行结果。

示例(Swift)

步骤 1: 导入 JavaScriptCore 框架

import JavaScriptCore

步骤 2: 创建 JSContext 对象

let jsContext = JSContext()

步骤 3: 执行 JavaScript 代码

jsContext?.evaluateScript("var a = 2 + 2")
if let result = jsContext?.evaluateScript("a") {print("Result: \(result.toInt32())") // 输出: Result: 4
}

示例代码

import JavaScriptCoreclass ViewController: UIViewController {var jsContext: JSContext!override func viewDidLoad() {super.viewDidLoad()jsContext = JSContext()// 在 JavaScript 中定义一个函数jsContext.evaluateScript("""function add(a, b) {return a + b;}""")// 在 Swift 中调用 JavaScript 函数if let addFunction = jsContext.objectForKeyedSubscript("add") {let result = addFunction.call(withArguments: [3, 4])print("Result of add function: \(result?.toInt32() ?? 0)") // 输出: Result of add function: 7}}
}

2. 在 JavaScript 中调用 Native 方法

通过 JavaScriptCore,可以将 Native 方法暴露给 JavaScript,这样就可以在 JavaScript 中调用这些方法。

示例(Swift)

步骤 1: 定义 Native 方法

let logFunction: @convention(block) (String) -> Void = { message inprint("Log from JavaScript: \(message)")
}

步骤 2: 将 Native 方法添加到 JSContext

jsContext.setObject(logFunction, forKeyedSubscript: "log" as NSString)

步骤 3: 在 JavaScript 中调用 Native 方法

jsContext.evaluateScript("""
log('Hello from JavaScript');
""")

示例代码

import JavaScriptCoreclass ViewController: UIViewController {var jsContext: JSContext!override func viewDidLoad() {super.viewDidLoad()jsContext = JSContext()// 定义一个 Native 方法let logFunction: @convention(block) (String) -> Void = { message inprint("Log from JavaScript: \(message)")}jsContext.setObject(logFunction, forKeyedSubscript: "log" as NSString)// 在 JavaScript 中调用 Native 方法jsContext.evaluateScript("""log('Hello from JavaScript');""")}
}

3. 完整示例:双向调用

完整代码示例

import JavaScriptCoreclass ViewController: UIViewController {var jsContext: JSContext!override func viewDidLoad() {super.viewDidLoad()jsContext = JSContext()// 定义一个 Native 方法let logFunction: @convention(block) (String) -> Void = { message inprint("Log from JavaScript: \(message)")}jsContext.setObject(logFunction, forKeyedSubscript: "log" as NSString)// 在 JavaScript 中定义一个函数jsContext.evaluateScript("""function add(a, b) {log('Adding ' + a + ' and ' + b);return a + b;}""")// 在 Swift 中调用 JavaScript 函数if let addFunction = jsContext.objectForKeyedSubscript("add") {let result = addFunction.call(withArguments: [3, 4])print("Result of add function: \(result?.toInt32() ?? 0)") // 输出: Result of add function: 7}// 在 JavaScript 中调用 Native 方法jsContext.evaluateScript("""log('Hello from JavaScript');""")}
}

小结

通过 JavaScriptCore,可以在 Native 代码中执行 JavaScript 代码,并在 JavaScript 中调用 Native 方法,实现跨语言调用。这种双向通信机制使得混合应用程序可以充分利用 JavaScript 和 Native 各自的优势,提升应用的功能性和用户体验。


异步还是同步 ?这是一个问题

使用 JavaScriptCore 进行跨语言调用(在 Native 代码中直接执行 JavaScript 代码,在 JavaScript 中调用 Native 方法),是异步还是同步的 ?

使用 JavaScriptCore 进行跨语言调用时,通常情况下调用是同步的。这意味着在 Native 代码中直接执行 JavaScript 代码时,调用会阻塞直到 JavaScript 代码执行完成,并且可以立即获取结果。同样地,在 JavaScript 中调用 Native 方法时,也是同步执行的。

详细解释

Native 代码中执行 JavaScript 代码

在 iOS 的 Swift/Objective-C 代码中,可以通过 JSContext 来执行 JavaScript 代码。调用 JSContext.evaluateScript 方法时,代码会同步执行,并且在执行完成后立即返回结果。

示例代码

import JavaScriptCoreclass ViewController: UIViewController {var jsContext: JSContext!override func viewDidLoad() {super.viewDidLoad()jsContext = JSContext()// 在 JavaScript 中定义一个函数jsContext.evaluateScript("""function add(a, b) {return a + b;}""")// 在 Swift 中调用 JavaScript 函数if let addFunction = jsContext.objectForKeyedSubscript("add") {let result = addFunction.call(withArguments: [3, 4])print("Result of add function: \(result?.toInt32() ?? 0)")}}
}

在这个示例中,evaluateScriptcall 方法都是同步的,执行 JavaScript 代码后立即返回结果。

JavaScript 中调用 Native 方法

通过 JavaScriptCore,可以在 JavaScript 中调用通过 JSContext 暴露的 Native 方法。这些调用同样是同步的,JavaScript 代码会等待 Native 方法执行完成,并获取结果。

示例代码

import JavaScriptCoreclass ViewController: UIViewController {var jsContext: JSContext!override func viewDidLoad() {super.viewDidLoad()jsContext = JSContext()// 定义一个 Native 方法let logFunction: @convention(block) (String) -> Void = { message inprint("Log from JavaScript: \(message)")}jsContext.setObject(logFunction, forKeyedSubscript: "log" as NSString)// 在 JavaScript 中调用 Native 方法jsContext.evaluateScript("""log('Hello from JavaScript');""")}
}

在这个示例中,JavaScript 中调用 log 方法会同步执行,Native 代码会立即执行打印操作。

同步执行的优缺点

优点
  1. 简单直观

    • 同步调用方式更容易理解和调试,因为代码按照顺序执行,没有复杂的回调和异步逻辑。
  2. 立即获取结果

    • 调用完成后可以立即获取执行结果,无需等待异步回调,适用于需要立即处理结果的场景。
缺点
  1. 可能阻塞线程

    • 如果 JavaScript 代码或 Native 方法执行时间较长,可能会阻塞当前线程,影响应用的响应性。
  2. 影响性能

    • 在主线程上进行耗时的同步操作可能会导致 UI 卡顿和用户体验下降。

如何处理耗时操作

为了避免同步调用带来的阻塞和性能问题,可以将耗时操作放到后台线程中执行。

示例代码

import JavaScriptCoreclass ViewController: UIViewController {var jsContext: JSContext!override func viewDidLoad() {super.viewDidLoad()jsContext = JSContext()// 定义一个耗时的 Native 方法let heavyTaskFunction: @convention(block) () -> String = {Thread.sleep(forTimeInterval: 2) // 模拟耗时操作return "Heavy task completed"}jsContext.setObject(heavyTaskFunction, forKeyedSubscript: "heavyTask" as NSString)// 在后台线程中执行 JavaScript 代码DispatchQueue.global().async {if let result = self.jsContext.evaluateScript("heavyTask()") {print("Result of heavy task: \(result.toString() ?? "")")}}}
}

在这个示例中,耗时操作被放到后台线程中执行,避免了阻塞主线程,确保了应用的响应性。

小结

使用 JavaScriptCore 进行跨语言调用时,调用通常是同步的。这种同步调用方式简单直观,可以立即获取结果,但可能会导致线程阻塞和性能问题。为了避免这些问题,可以将耗时操作放到后台线程中执行,确保应用的响应性和用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/40460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手把手教你一步一步通过AI助手生成利润表分析报告

AI助手之利润表分析报告-操作篇 以下为文字整理部分: 如果要手工制作一份这样的利润分析报告大概要多久时间?从准备数据做成表格,到完成报告,至少需要1天的时间吧,特别是敲文字报告的时候,生怕把数字搞错要…

什么是森林防火气象站?作用?

森林防火气象站用精准的数据和先进的技术,守护着森林的安全。本文将带您了解其重要性、工作原理以及在森林防火中的实际应用。 一、森林防火气象站的重要性 森林火灾是森林生态系统的大敌,它能在短时间内烧毁大片森林,破坏生态平衡&#xff0…

5、Redis 缓存设计相关知识点

1. 多级缓存架构 多级缓存架构是一种通过在应用层和数据库层之间添加多个缓存层来提高系统性能和可用性的架构设计。这种设计能够有效减少数据库负载,并提高数据访问速度。常见的多级缓存包括本地缓存、分布式缓存和数据库缓存。 本地缓存:本地缓存位于应用服务器本地,响应…

高通平台Display显示架构

目录 一、显示整体架构二、SurfaceFlinger三、HWC四、Gralloc五、DisplayManagerService六、WindowManagerService 一、显示整体架构 二、SurfaceFlinger SurfaceFlinger是一个系统服务,如:audioflinger等等,这个系统服务主要实现了Surface的…

通过升级nginx完美修复nginx相关漏洞

目录 前言1 安全评估报告的漏洞信息1.1 nginx漏洞概况1.2 nginx漏洞详细信息1.3 安装的软件信息 2 问题分析3 Nginx从1.18版本升级到1.26版本的步骤与说明3.1 查看现有Nginx配置参数3.2 下载新版本Nginx3.3 配置新版本Nginx3.4 编译新版本Nginx3.5 备份旧版本Nginx的二进制文件…

github 设置中文,亲测有效

点进去 安装 选上面第二个,不行再选第一个 GitHub - maboloshi/github-chinese: GitHub 汉化插件,GitHub 中文化界面。 (GitHub Translation To Chinese)

常见网络攻击方式及防御方法

1. DDOS攻击(分布式拒绝服务攻击) 概念:借助于C/S(客户端/服务器)技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDOS攻击,从而成倍地提高拒绝服务攻击的威力。防护方…

springboot 配置加密,jasypt加解密命令

位置:Maven仓库中\org\jasypt\jasypt\1.9.3 java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input123456 passwordmysalt algorithmPBEWithMD5andDES ----ENVIRONMENT----------------- Runtime: Oracle Corporation Java HotSpot™…

sideloadly 苹果自签和sidestore手机续签ipa记录

sideloadly 地址:https://sideloadly.io/#download 直接安装对应系统软件,然后吧ipa 拖到里面续签,缺点每7天需要电脑续签 如果续签保留数据需要对应的位置开启 enable file sharing 勾选 和 bundle id 修改 注意的地方需要电脑和手机appi…

气象观测站:时刻注视着天空的变化

在广袤无垠的地球上,气象观测站时刻注视着天空的变化,记录着大自然的脉动。它们是我们理解和应对气候变化、极端天气事件的重要工具。 一、气象观测站的基本构成 气象观测站包括一系列的气象仪器和设备,用于测量和记录各种气象参数。这些参数…

软考《信息系统运行管理员》-2.5信息系统运维管理系统与专用工具

2.5信息系统运维管理系统与专用工具 信息系统运维管理系统功能框架 信息系统运维管理系统是站在运维管理的整体视角,基于运维流程,以服务为导向的业务 服务管理和运维管理支撑平台,提供统一管理门户,最终帮助运维对象实现信息系…

【AI原理解析】-AI native模型微调

目录 一、模型微调的定义与重要性 二、模型微调的步骤 三、模型微调的优势与挑战 四、模型微调的应用场景 五、模型微调的未来发展方向 一、模型微调的定义与重要性 定义:模型微调是指在预训练模型的基础上,使用特定任务的数据对模型进行再训练&am…

Zabbix 配置SNMP监控

Zabbix SNMP监控介绍 Zabbix提供了强大的SNMP监控功能,可以用于监控网络设备、服务器和其他支持SNMP协议的设备。SNMP(Simple Network Management Protocol,简单网络管理协议)是一种广泛用于网络管理的协议。它用于监控网络设备&…

CVPR 2024最佳论文分享:打破刚性的超分辨率图像处理GNN

CVPR 2024最佳论文分享:打破刚性的超分辨率图像处理GNN CVPR(Conference on Computer Vision and Pattern Recognition)是计算机视觉领域最有影响力的会议之一,主要方向包括图像和视频处理、目标检测与识别、三维视觉等。近期&am…

分布式数据库HBase:从零开始了解列式存储

在接触过大量的传统关系型数据库后你可能会有一些新的问题: 无法整理成表格的海量数据该如何储存? 在数据非常稀疏的情况下也必须将数据存储成关系型数据库吗? 除了关系型数据库我们是否还有别的选择以应对Web2.0时代的海量数据? 如果你也曾经想到过这些问题, 那么HBase将是…

C++: 左值引用和右值引用

目录 概念: 理解: 左值引用,右值引用 左值引用能否给右值取别名? 右值引用能否给左值取别名? 引用的意义是什么? 左值和右值对自定义类型有什么区别吗? move的妙用! 没有优化…

LLMs之CriticGPT:CriticGPT的简介、安装和使用方法、案例应用之详细攻略

LLMs之CriticGPT:CriticGPT的简介、安装和使用方法、案例应用之详细攻略 目录 CriticGPT的简介 1、简介 2、CriticGPT的方法 2.1、CriticGPT的训练方法 2.2、CriticGPT的批评生成方法 3、局限性 4、后续步骤 CriticGPT的安装和使用方法 CriticGPT的案例应用…

“proxy_pass“ directive is duplicate

后面发现是nginx.conf里面proxy pass这里有两个,注释其中一个并重新运行即可!

AI并不是开发者的敌人,而是帮助他们实现更高效工作的得力助手。

AI是在帮助开发者还是取代他们? 在软件开发领域,生成式人工智能(AIGC)正在改变开发者的工作方式。无论是代码生成、错误检测还是自动化测试,AI工具正在成为开发者的得力助手。然而,这也引发了对开发者职业前…

基于主流SpringBoot进行JavaWeb开发的学习路线

目录 一、学习路线 (1)第一部分(Web前端开发的技术栈) (2)第二部分(Web后端开发) 二、学习之后必备的技能 三、学习Web开发的基础与未来的收获 学完这一类知识目标:…