从应用程序内部评估JavaScript(JavaScript(JS)是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。JavaScript 是属于 HTML 和 Web 的编程语言。)程序,并支持应用程序的JavaScript脚本。
概述
JavaScriptCore框架提供了从Swift、Objective-C和基于c的应用程序中评估JavaScript程序的能力。您还可以使用JavaScriptCore向JavaScript环境插入定制对象。
类
1.JSContext JSContext对象表示JavaScript执行环境。您创建并使用JavaScript上下文来评估来自Objective-C或Swift代码的JavaScript脚本,访问在JavaScript中定义或计算的值,以及使JavaScript可以访问本机对象、方法或函数。
2.JSManagedValue JSManagedValue对象封装JSValue对象,添加“条件保留”行为来提供值的自动内存管理。托管值的主要用例是将JavaScript值存储在Objective-C或Swift对象中,该对象本身被导出到JavaScript。
3.JSValue JSValue实例是对JavaScript值的引用。您可以使用JSValue类在JavaScript和Objective-C或Swift表示之间转换基本值(比如数字和字符串),以便在本机代码和JavaScript代码之间传递数据。您还可以使用这个类来创建JavaScript对象,这些对象包装自定义类或JavaScript函数的本机对象,其实现由本机方法或块提供。
4.JSVirtualMachine JSVirtualMachine实例表示用于JavaScript执行的自包含环境。使用该类有两个主要目的:支持并发JavaScript执行,以及管理连接在JavaScript和Objective-C或Swift之间的对象的内存。
协议-Protocols---JSExport 将Objective-C类及其实例方法、类方法和属性导出到JavaScript代码的协议。
JSBase.h 定义JavaScriptCore接口引擎。
JSContextRef.h JSObjectRef.h 一个JavaScript对象。
JSStringRef.h 一个UTF16字符缓冲区,它是JavaScript中的基本字符串表示。
JSStringRefCF.h 包含CFString便利方法。
JSValueRef.h 一个JavaScript值,它是所有JavaScript值及其上的多态函数的基类型。
JSContext
SContext对象表示JavaScript执行环境。您创建并使用JavaScript上下文来评估来自Objective-C或Swift代码的JavaScript脚本,访问在JavaScript中定义或计算的值,以及使JavaScript可以访问本机对象、方法或函数。
创造JSContext对象
init 初始化一个新的JavaScript上下文。
initWithVirtualMachine: 创建与特定虚拟机关联的新JavaScript上下文。
评估脚本
evaluateScript: 执行指定的JavaScript代码。
evaluateScript:withSourceURL: 执行指定的JavaScript代码,将指定的URL视为其源位置。
检查正在运行的互斥量中的回调状态
currentContext 返回当前执行JavaScript代码的上下文。
currentCallee 返回当前执行的JavaScript函数。
currentThis 返回当前执行JavaScript代码中此关键字的值。
currentArguments 从JavaScript代码返回当前本机回调的参数。
使用JavaScript全局状态
globalObject 与上下文关联的JavaScript全局对象。
exception 在脚本的计算中抛出一个JavaScript异常。
exceptionHandler 要调用的块应该在抛出JavaScript异常时评估脚本结果。
virtualMachine 上下文所属的JavaScript虚拟机。
name 上下文的描述性名称。
使用下标访问JavaScript全局状态
- objectForKeyedSubscript:
返回上下文的全局对象中指定的JavaScript属性的值,允许使用下标getter语法。
- setObject:forKeyedSubscript:
设置上下文的全局对象的指定JavaScript属性,允许使用下标setter语法。
使用C JavaScriptCore API
JSGlobalContextRef 返回JavaScript上下文的C表示形式。
- contextWithJSGlobalContextRef: 从等价的C表示创建JavaScript上下文对象。
JSManagedValue
JSManagedValue对象封装JSValue对象,添加“条件保留”行为来提供值的自动内存管理。托管值的主要用例是将JavaScript值存储在Objective-C或Swift对象中,该对象本身被导出到JavaScript。
重要的
不要在导出到JavaScript的本机对象中存储非托管JSValue对象。因为JSValue对象引用它所包含的JSContext对象,所以这个操作创建了一个retain循环,从而避免释放上下文。
托管值的“条件保留”行为确保只要以下条件为真,托管值的底层JavaScript值就会被保留:
JavaScript值可以通过JavaScript对象图访问(即不受JavaScript垃圾收集的影响)
JSManagedValue对象可以通过Objective-C或Swift对象图访问,正如使用addManagedReference(_:withOwner:)方法向JavaScriptCore虚拟机报告的那样
但是,如果这两个条件都不为真,则托管值将其value属性设置为nil,释放底层JSValue对象。
创造Managed Value
- initWithValue:使用指定的JavaScript值初始化托管值。
managedValueWithValue:使用指定的JavaScript值创建托管值。
managedValueWithValue:andOwner:创建托管值并将其与所有者关联。
访问Managed Value
value---托管值的底层JavaScript值。
JSValue
JSValue实例是对JavaScript值的引用。您可以使用JSValue类在JavaScript和Objective-C或Swift表示之间转换基本值(比如数字和字符串),以便在本机代码和JavaScript代码之间传递数据。您还可以使用这个类来创建JavaScript对象,这些对象包装自定义类或JavaScript函数的本机对象,其实现由本机方法或块提供。
每个JSValue实例都源自一个JSContext对象,该对象表示包含该值的JavaScript执行环境。该值持有对其上下文对象的强引用——只要保留与特定JSContext实例相关联的任何值,该上下文就仍然是活动的。当在JSValue对象上调用实例方法,并且该方法返回另一个JSValue对象时,返回的值属于与原始值相同的上下文。
每个JavaScript值还与一个特定的JSVirtualMachine对象关联(通过上下文属性间接关联),该对象表示其上下文的底层执行资源集。您只能将JSValue实例传递给同一虚拟机承载的JSValue和JSContext实例上的方法,试图将一个值传递给另一个虚拟机会引发Objective-C异常。
在JavaScript和本机类型之间进行转换
当您使用以下方法创建JavaScript值、读取和转换JavaScript值时,JavaScriptCore会自动将本机值转换为JavaScript值,反之亦然,使用下面总结的规则。
1.NSDictionary对象或Swift字典及其包含的键将成为具有匹配的命名属性的JavaScript对象,反之亦然。键值是递归复制和转换的。
2.NSArray对象或Swift数组变成JavaScript数组,反之亦然,元素递归地复制和转换。
3.Objective-C块(或带有@convention(block)属性的Swift闭包)变成JavaScript函数对象,参数和返回类型使用与值相同的规则转换。转换由本机块或方法支持的JavaScript函数返回该块或方法;所有其他JavaScript函数都转换为空字典。
- 对于所有其他本机对象类型(以及类类型或元类型),JavaScriptCore创建一个JavaScript包装器对象,其中包含一个反映本机类层次结构的构造函数原型链。默认情况下,原生对象的JavaScript包装器不会使该对象的属性和方法在JavaScript中可用。
JSExport---将Objective-C类及其实例方法、类方法和属性导出到JavaScript代码的协议。
将Objective-C对象导出到JavaScript
当您从Objective-C类的实例创建JavaScript值,而JSValue类没有指定复制约定时,JavaScriptCore创建一个JavaScript包装器对象。(对于某些类,JavaScriptCore会自动将值复制到适当的JavaScript类型;例如,NSString实例变成JavaScript字符串。)
在JavaScript中,通过原型对象链支持继承。对于导出的每个Objective-C类,JavaScriptCore都在包含的JavaScript上下文(JSContext对象)中创建一个原型。对于NSObject类,prototype对象是JavaScript上下文的对象原型。对于所有其他Objective-C类,JavaScriptCore创建了一个prototype对象,它的内部[prototype]属性指向为Objective-C类的超类创建的prototype属性。因此,JavaScript包装器对象的原型链反映了被包装的Objective-C类型的继承层次结构。
除了原型对象之外,JavaScriptCore还为每个Objective-C类生成一个JavaScript构造函数对象。
将Objective-C方法和属性暴露给JavaScript
默认情况下,Objective-C类的任何方法或属性都不会暴露给JavaScript;相反,您必须选择要导出的方法和属性。对于类所遵循的每个协议,如果协议包含JSExport协议,那么JavaScriptCore将该协议解释为要导出到JavaScript的方法和属性列表。
对于导出的每个实例方法,JavaScriptCore都创建一个对应的JavaScript函数作为原型对象的属性。对于每个导出的Objective-C属性,JavaScriptCore都会在原型上创建一个JavaScript访问器属性。对于导出的每个类方法,JavaScriptCore在构造函数对象上创建一个JavaScript函数。例如,清单1和清单2演示了JSExport协议的采用,以及用JavaScript导出的类所表示的API。
实战------OC和JavaScript交互
test.html
Objective-C和JavaScript交互