最近接手 了一个老项目,其中用到了JavaScriptCore 库,但是里面大部分是C API的接口和使用,由于之前都是接触OC API,对于底层的封装,很是手生,特此记录学习一下。
JavaScriptCore介绍
JavaScriptCore 是 JavaScript 引擎,通常会被叫做虚拟机,专门设计来解释和执行 JavaScript 代码,可以理解为一个浏览器的运行内核。
JavaScriptCore Framework 是 iOS7 引入的新功能,其实就是基于 Webkit 中以 C/C++ 实现的 JavaScriptCore 的一个封装,大多数 iOS 比较熟悉的是它的 Objective-C API,可以用简介的方式 JS 与Native 通讯,其实它还有C API的部分,虽然也是开源的,但是在查看源代码时只有较少的介绍,而且我们知道 Objective-C API 只是 C API 接口的封装。本文主要介绍 C API 部分,帮助大家更好理解 JavaScriptCore Framework。
JavaScriptCore C API
JSGlobalContextRef:執行 JS 的 context
JSValueRef:在 JavaScript 中所使用的各種資料,包括字串、數字以及 function,都會包裝成 Value,我們可以從數字、JSStringRef 或 JSObject 產生 JSValueRef,也可以轉換回來。需要特別注意的是,JS 裡頭的 null 也是一個 JSValueRef(JSValueMakeUndefined 與 JSValueMakeNull)。
JSStringRef:JavaScriptCore 使用的字串。用完記得要 release。
JSObjectRef:JS Array、Function 等。
JavaScriptCore C API 部分包含六个类 下面我们详细解释每个类的作用及用法
- JSBase.h
//JavaScriptCore 的接口文件,这个类中 import 了其他的类,简单封装了其他的 C API。
- JSContextRef.h
//JSContextRef 相当于 Objective-C 中的 JSContext,主要提供 JS 执行的上下文环境。
- JSObjectRef.h
//JSObjectRef 相当于 Objective-C 中的 JSObject,它代表一个JavaScript对象,交互的核心放在都在这个类中实现。
- JSStringRef.h
//是 JavaScript 中基本的字符串表示形式。
- JSStringRefCF.h
//包含 CFString 便利的方法。
- JSValueRef.h
//JSValueRef 相当于 Objective-C 中的 JSValue ,对应一个 JavaScript 的值,它是所有JavaScript值的基本类型
与JS运行环境相关的方法如下:
//创建一个JSContextRef组
/*
JSContextRef相当于JSContext,同一组中的数据可以共享
*/
JSContextGroupRef JSContextGroupCreate(void);
//内存引用
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group);
//内存引用释放
void JSContextGroupRelease(JSContextGroupRef group);
//创建一个全局的运行环境
JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass);
//同上
JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass);
//内存引用
JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx);
//内存引用释放
void JSGlobalContextRelease(JSGlobalContextRef ctx);
//获取全局对象
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);
//获取JSContextRef组
JSContextGroupRef JSContextGetGroup(JSContextRef ctx);
//获取全局的运行环境
JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx);
//获取运行环境名
JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx);
//设置运行环境名
void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name);
与定义JS对象的相关方法如下:
//定义JS类
/*
参数JSClassDefinition是一个结构体 其中可以定义许多回调
*/
JSClassRef JSClassCreate(const JSClassDefinition* definition);
//引用内存
JSClassRef JSClassRetain(JSClassRef jsClass);
//释放内存
void JSClassRelease(JSClassRef jsClass);
//创建一个JS对象
JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data);
//定义JS函数
JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction);
//定义构造函数
JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor);
//定义数组
JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
//定义日期对象
JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
//定义异常对象
JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
//定义正则对象
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
//定义函数对象
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception);
//获取对象的属性
JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object);
//设置对象的属性
void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value);
//检查对象是否包含某个属性
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);
//获取对象属性
JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
//定义对象属性
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception);
//删除对象属性
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
//获取数组值
JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception);
//设置数组值
void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception);
//获取私有数据
void* JSObjectGetPrivate(JSObjectRef object);
//设置私有数据
bool JSObjectSetPrivate(JSObjectRef object, void* data);
//判断是否为函数
bool JSObjectIsFunction(JSContextRef ctx, JSObjectRef object);
//将对象作为函数来调用
JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
//判断是否为构造函数
bool JSObjectIsConstructor(JSContextRef ctx, JSObjectRef object);
//将对象作为构造函数来调用
JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
//获取所有属性名
JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object);
//进行内存引用
JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array);
//内存释放
void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array);
//获取属性个数
size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array);
//在属性名数组中取值
JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index);
//添加属性名
void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName);
待续