# JavascriptCore 1、JSCore 是基于 webkit 以 C/C++ 实现的一个 js 包装,让 js 和 Native 交互变得更加简单。 - JScontext JSContext 代表一个 JavaScript 的执行环境的一个实例。所有JavaScript执行都是在上下文内进行。JSContext还用于管理对象的生命周期内 JavaScript 的虚拟机 - JSValue JSValue 是用来接收 JSContext 执行后的返回结果。JSValue 可以是 JS 的任意类型(变量、对象、函数...) - JSManagedValue JSManagedValue 是对 JSValue 的封装,可以解决 JS 和 OC 之间循环引用的问题。JSManagedValue 最常用的用法就是安全的从内存堆区里面引用 JSValue 对象.如果 JSValue 存储在内存的堆区的方式是不正确的,很容易造成循环引用,然后导致 JSContext 对象不能正确的释放掉. - JSExport 是一个协议,用来将 Native 对象暴露给 JS,这个对象可以指向给自身和别的对象。 - JSVirtualMachine 管理 JS 对象空间和所需的资源 2、Native 调用 JS - 加载 JS 代码 (JSValue *)evaluateScript:(NSString *)script; - 调用 JS 方法 JSvalue *callBack = self.context[@"sayHi"]; [callback callWithArguments:@[@"杭城小刘"]]; 3、JS 调用 Native - 通过 Block 实现。然后在 JS 中直接调用方法即可。需要注意的是在 Block 内部不要直接使用外部定义的 JScontext 对象或 JSValue ,应该作为参数传递进来,或者通过 + (JSContext *)currentContext; 来获取。否则会造成循环引用、内存无法被正确回收 self.context[@"showMessage"] = ^(NSString *message){ UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]; [alertCtr addAction:cancel]; //注意:方法是在子线程中执行的,需要跟新UI的话,需要切入主线程。 dispatch_async(dispatch_get_main_queue(), ^{ [weakSealf presentViewController:alertCtr animated:YES completion:nil]; }); }; - 通过 JSExport 协议实现; JS 需要通过 OC 中注入的对象来调方法,那么方法需要在协议中声明,并且在注入的对象中实现;在 webview 加载完成的时候注入实现协议的 Native 对象 //声明协议 @proptocol JSInject - (void)showMessage:(NSString *)message; @end //实现相应的协议 - (void)showMessage:(NSString *)message{ UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]; [alertCtr addAction:cancel]; //注意:方法是在子线程中执行的,需要跟新UI的话,需要切入主线程。 dispatch_async(dispatch_get_main_queue(), ^{ [weakSealf presentViewController:alertCtr animated:YES completion:nil]; }); } //注入 - (void)webViewDidFinishLoad:(UIWebView *)webView { //从webview上获取相应的JSContext。 self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; //注入JS需要的“OC”对象 self.context[@"Bridge"] = [JSInject new]; } 举个🌰 JS call Native //对外要暴露的 native 对象(其中挂载了一些属性和方法) #import #import @protocol PersonInjectExport @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *hobby; - (id)sayHi; @end @interface PersonInject : NSObject @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *hobby; - (id)sayHi; @end // viewcontroller - (void)webViewDidFinishLoad:(UIWebView *)webView{ self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; PersonInject *person = [[PersonInject alloc] init]; person.name = @"杭城小刘"; person.hobby = @"Coding、Movie、Music、Table tennis、Fit"; self.jsContext[@"lbp"] = person; } //JS 嗨。大家好我是

***

Native call JS //Native - (void)callJS{ JSValue *functionName = self.jsContext[@"sum"]; NSInteger sum = [[functionName callWithArguments:@[@"2",@"18"]] toInt32];; UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"来自JS 的计算" message:[NSString stringWithFormat:@"%zd",sum] preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]; [alertVC addAction:okAction]; [self presentViewController:alertVC animated:YES completion:nil]; } //JS function sum(a ,b){ return parseInt(a) + parseInt(b); }