一. JavaScriptCore 簡介
首先要區(qū)分JavaScriptCore 和 JavaScriptCore 框架:
JavaScriptCore框架是一個蘋果在iOS7引入的框架盈包,該框架讓 Objective-C 和 JavaScript 代碼直接的交互變得更加的簡單方便呢燥。
而JavaScriptCore是蘋果Safari瀏覽器的JavaScript引擎叛氨,JavaScriptCore在性能上也不輸V8引擎了。
執(zhí)行一段js代碼:
? JSContext *context = [[JSContext alloc]init];
?JSValue*value = [contextevaluateScript:@"2+2"];
?NSLog(@"%d",[valuetoInt32]);
JSContext:
JSContext 為JS代碼的執(zhí)行提供了上下文環(huán)境焊夸,通過jSCore執(zhí)行的JS代碼都得通過JSContext來執(zhí)行淳地。
JSValue:
JSValue 是對 JS 值的包裝
oc執(zhí)行一段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對象類型撞叽,對應(yīng)到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){
? ? //調(diào)用oc函數(shù)makeNSColor
? ? return makeNSColor(color);
};
oc代碼:JSContext *context = [[JSContext alloc]init];
? ? context[@"makeNSColor"] = ^float(NSDictionary *colors){ ?//js中的函數(shù)對象相當(dāng)于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調(diào)用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調(diào)用OC系統(tǒng)類 :
自定義協(xié)議(UILabelJSExport) :
@protocol UILabelJSExport<JSExport>
? ?@property(nonatomic,strong)NSString*text;
@end
JS調(diào)用OC系統(tǒng)類 :
- (void)jsCallOCSystemClass{
// 給系統(tǒng)類添加協(xié)議
class_addProtocol([UILabelclass],@protocol(UILabelJSExport));
// 創(chuàng)建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設(shè)置文本內(nèi)容
NSString*jsCode =@"label.text = 'Oh Year'";
?[ctx evaluateScript:jsCode];
}