JSExport 协议配套一个例子:JavaScriptCoreBox
JavaScriptCore 中主要的类有
JSVirtualMachine 的实例JSVirtualMachine 的实例,因为 JavaScript 本身是单线程的JSVirtualMachine 实例都会有自己的堆和垃圾回收器,因此,多个 JSVirtualMachine 实例间并不能传递信息JSVirtualMachine 实例来运行 JavaScript 代码JSContext 是一个 JavaScript 执行的上下文window 对象JSContext 对象JSContext 对象之间可以互相传递信息JSContext 出来到 Native 的数据,它们的类型都是 JSValueJSValue 的封装JSValue 的内存JSExport 协议
JSVirtualMachine,JSContext,JSValue三者的关系

JSContext 实例[context evaluateScript:jscode] 来直接运行 JavaScript 代码或注册 JavaScript 代码若在 2 中注册了 JavaScript 代码,如,注册了一个方法 foo, 则可以通过
JSValue *fooFunction = [self.context objectForKeyedSubscript:@"foo"];
// 或者,两种方法的效果一样,但在 Swift 中只可以使用 👆
JSValue *fooFunction = self.context[@"foo"];
来获取到 foo 方法,从 JavaScript 返回来的值都是 JSValue 类型
获取到 JavaScript 方法后,可以直接调用
NSArray *result = [[fooFunction callWithArguments:@[@(TheArgument)]] toArray];
callWithArguments 中,如果没有参数传递,则直接传 nilJSValue 类型,要转为 Native 对象,则需要调用类似 toArray 的方法来进行转换// 注册
self.context[@"outterLog"] = ^(NSString *logMsg) {
return [NSString stringWithFormat:@"outterLog: %@", logMsg];
};
// 调用
NSString *result = [[self.context evaluateScript:@"outterLog('hey, log from outter')"] toString];
self.tvReturnValue.text = [NSString stringWithFormat:@"innerLog: %@", result];
// 注册
// 注意 retain cycle
__weak typeof(self) weakSelf = self;
self.context[@"innerLog"] = ^(NSString *logMsg) {
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.tvWithoutReturnValue.text = [NSString stringWithFormat:@"innerLog: %@", logMsg];
});
};
// 调用
[self.context evaluateScript:@"innerLog('hey, log from inner')"];
JSContext)等信息,可以使用 JSContext 本身提供的类方法,这样就不用 weak-strong dancing 了
currentContextcurrentCalleecurrentThiscurrentArgumentsJSExport 协议自定义一个协议,继承于 JSExport 协议,如
@protocol HumanJSable<JSExport>
@property (nonatomic, copy) NSString *name;
- (NSString *)nameIt;
@end
JSContext 中通过 JavaScript 代码直接调用
Human *human = [[Human alloc] initWithName:@"Alice" age:20];
self.context[@"human"] = human;
NSString *name = [[self.context evaluateScript:@"human.nameIt()"] toString];
self.tvResult.text = name;
JSContext 对象中创建一个原型NSObject 类,原型对象就是 JSContext 的 Object 原型[Prototype] 指向 Objective-C 类的父类JSExport 协议的自定义协议中,这样,JavaScriptCore 将该协议中的方法和属性解释成一个表