JavaScriptCore

一. JavaScriptCore 简介

首先要区分JavaScriptCore 和 JavaScriptCore 框架:

JavaScriptCore框架是一个苹果在iOS7引入的框架,该框架让 Objective-C 和 JavaScript 代码直接的交互变得更加的简单方便。

而JavaScriptCore是苹果Safari浏览器的JavaScript引擎,JavaScriptCore在性能上也不输V8引擎了。

执行一段js代码:

  JSContext *context = [[JSContext alloc]init];

 JSValue*value = [contextevaluateScript:@"2+2"];

 NSLog(@"%d",[valuetoInt32]);

JSContext:

JSContext 为JS代码的执行提供了上下文环境,通过jSCore执行的JS代码都得通过JSContext来执行。

JSValue:

JSValue 是对 JS 值的包装

oc-js


oc执行一段js代码:

方式一:

test.js:

var factorial = function(l,r){   return  l+r; };

oc代码:

NSString*path =  [[NSBundle mainBundle]pathForResource:@"test" ofType:@"js"];

NSString *valueString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

 JSContext *context = [[JSContext alloc]init];

 [context evaluateScript:valueString];  //载入js代码

JSValue*value = [context evaluateScript:@"factorial(2,3)"];       

 NSLog(@"%d",[valuetoInt32]);  //输出:5

方式二:

。。。。

 JSValue*func = context[@"factorial"];

 JSValue*result = [funccallWithArguments:@[@3,@4]];

  NSLog(@"%d",[resulttoInt32]); //输出7

注:JS中的object对象类型,对应到OC中就是字典类型,这种类似字典的下标方式不仅可以取值,也可以存值。不仅可以作用于Context,也可以作用与JSValue。

2.JavaScript 与 Objective-C 交互

JavaScript 与 Objective-C 交互主要通过2种方式,Block和JSExport

1.Block方式:

js代码:var colorMap = {

    "red":254,

    "green":100,

    "blue":200,

};

var colorForWord =function(color){

    //调用oc函数makeNSColor

    return makeNSColor(color);

};

oc代码:JSContext *context = [[JSContext alloc]init];

    context[@"makeNSColor"] = ^float(NSDictionary *colors){  //js中的函数对象相当于oc中的block

        float r = [colors[@"red"] floatValue];

        return r;

    };

    NSString*path =  [[NSBundle mainBundle]pathForResource:@"test" ofType:@"js"];

    NSString *valueString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

    [context evaluateScript:valueString];

//js调用oc

    JSValue *value = [context evaluateScript:@"colorForWord(colorMap)"];

     NSLog(@"%f",[value toDouble]);

注意:

不要在Block中直接使用JSValue

不要在Block中直接使用JSContext

因为Block会强引用它里面用到的外部变量,如果直接在Block中使用JSValue的话,那么这个JSvalue就会被这个Block强引用,而每个JSValue都是强引用着它所属的那个JSContext的

2.JSExport方式

ViewController.h :

@protocol TestJSExport <JSExport>

- (void)testOC;

@end

@interface ViewController :UIViewController

@property (strong, nonatomic) JSContext *context;

@end

ViewController.m :

- (void)viewDidLoad {

    [super viewDidLoad];

    self.context= [[JSContextalloc]init];

    self.context[@"native"] =self;

    NSString*path =  [[NSBundle mainBundle]pathForResource:@"JSCallOC" ofType:@"js"];

    NSString *valueString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

    [self.contextevaluateScript:valueString];

}

- (void)testOC{

    NSLog(@"test oc");

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{

    [self.context evaluateScript:@"colorForWord()"];

}

JSCallOC.js :

var colorForWord =function(){

        native.testOC();

};

JS调用OC系统类 :

自定义协议(UILabelJSExport) :

@protocol UILabelJSExport<JSExport>

   @property(nonatomic,strong)NSString*text;

@end

JS调用OC系统类 :

- (void)jsCallOCSystemClass{

// 给系统类添加协议

class_addProtocol([UILabelclass],@protocol(UILabelJSExport));

// 创建UILabel

UILabel*label = [[UILabelalloc] initWithFrame:CGRectMake(50,50,100,100)]; [self.view addSubview:label]; 

 JSContext *ctx = [[JSContext alloc] init];

// 就会在JS中生成label对象,并且用laebl引用

ctx[@"label"] = label;

// 利用JS给label设置文本内容

NSString*jsCode =@"label.text = 'Oh Year'";

 [ctx evaluateScript:jsCode];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容