JavaScriptCore框架的类
JavaScriptCore框架对外暴露的类实际上非常少,这样带来的好处是API非常简单。如下图所示,只有5个类,分别是JSContext,JSValue,JSManagedValue,JSVirtualMachine,JSExport,其中最核心的是JSContext和JSValue,我们平时打交道的基本就是这两个类了。
这些类的基本介绍如下:
JSVirtualMachine | A JSVirtualMachine instance represents a self-contained environment for JavaScript execution. |
JSContext | A JSContext object represents a JavaScript execution environment. |
JSValue | A JSValue instance is a reference to a JavaScript value. |
JSExport | The JSExport protocol provides a declarative way to export Objective-C instance classes and their instance method, class methods, and properties to JavaScript code. (注意这里只能是OC) |
JSManagedValue | A JSManagedValue object wraps a JSValue object, adding “conditional retain” behavior to provide automatic memory management of values. |
JSVirtualMachine
“A JSVirtualMachine instance represents a self-contained environment for JavaScript execution.”,这段话是官方文档中对JSVirtualMachine的定义,我们使用JSVirtualMachine的目的主要有两个:支持JavaScript并发执行,管理用于衔接JavaScript 与 OC(Swift) 代码的对象的内存。
1.Threading and Concurrent JavaScript Execution
每一个JavaScript content (a JSContext Object) 都属于一个VM (virtual machine) ,但一个virtual machine则能包含多个context。同时,对于运行在同一个VM的多个context,VM运行在它们之间互相传递values (JSValue Object)。但是,不同virtual machine之间则是相互隔绝的,即你不能将一个VM中的value传递到另外一个VM的context中。
JavaScriptCore API 是线程安全的,比如,你可以在任意线程中创建JSValue或者执行scripts,但是,同一个时间其他尝试使用这个VM的线程都会处于等待状态。如果需要在多线程中并发执行JS,为每个thread创建单独的 JSVirtual Machine即可。
2.Managing Memory for Exported Objects
注意,当我们 export 一个 OC 或 Swift object 到 JS 中时,不能在这个object 中存储对应的 JS values。这种行为会导致一个retain cycle,JSValue objects 持有他们对应的 JSContext 的强引用,JSContext 则持有export到JS的native object的强引用,即 native object(OC or Swift object) —> JSValue —> JSContext —> native object。
解决方法是使用JSManagedValue来有条件地持有JavaScript value,同时向VM报告这个managed value的native ownership chain。