JSExport
协议配套一个例子:JavaScriptCoreBox
JavaScriptCore 中主要的类有
JSVirtualMachine
的实例JSVirtualMachine
的实例,因为 JavaScript 本身是单线程的JSVirtualMachine
实例都会有自己的堆和垃圾回收器,因此,多个 JSVirtualMachine
实例间并不能传递信息JSVirtualMachine
实例来运行 JavaScript 代码JSContext
是一个 JavaScript 执行的上下文window
对象JSContext
对象JSContext
对象之间可以互相传递信息JSContext
出来到 Native 的数据,它们的类型都是 JSValue
JSValue
的封装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
中,如果没有参数传递,则直接传 nil
JSValue
类型,要转为 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 了
currentContext
currentCallee
currentThis
currentArguments
JSExport
协议自定义一个协议,继承于 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 将该协议中的方法和属性解释成一个表