一丶原理
1.利用<JavaScriptCore/JavaScriptCore.h> 可以实现js和oc的消息传递;
2.利用反射机制,根据消息处理对应事情;
3.利用oc语言的动态特性,动态地创建对象,实现对象方法;
二丶原理探索
利用<JavaScriptCore/JavaScriptCore.h>
JSContext *context = [[JSContext alloc] init];
context[@"hello"] = ^(NSString *msg){
NSLog(@"%@",msg);
};
[context evaluateScript:@"hello('word')"];
生成一个View 的OC代码:
//原生实现
UIView *redView = [[UIView alloc] init];
redView.frame = CGRectMake(0, 0, 100, 100);
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
利用反射机制
NSDictionary *creatClassDict = @{@"class":@"UIView",
@"backgroundColor":@{@"key":@"backgroundColor",@"class":@"UIColor",@"value":@"yellowColor"},
@"selector":@"addSubview:",
@"frame":@{@"key":@"frame",@"value":@"{{100, 100}, {100, 100}}"}
};
//反射机制
Class objClass = NSClassFromString(creatClassDict[@"class"]);
id yellowView = [[objClass alloc] init];
Class colorClass = NSClassFromString(creatClassDict[@"backgroundColor"][@"class"]);
SEL colorSelector = NSSelectorFromString(creatClassDict[@"backgroundColor"][@"value"]);
IMP colorImp = [colorClass methodForSelector:colorSelector];
id (*colorfunc)(id, SEL) = (void *)colorImp;
id color = colorfunc(colorClass, colorSelector);
[yellowView setValue:color forKey:creatClassDict[@"backgroundColor"][@"key"]];
[yellowView setValue:[NSValue valueWithCGRect:CGRectFromString(creatClassDict[@"frame"][@"value"])] forKey:creatClassDict[@"frame"][@"key"]];
SEL selector = NSSelectorFromString(creatClassDict[@"selector"]);
IMP imp = [self.view methodForSelector:selector];
void *(*func)(id, SEL, UIView *) =(void *) imp;
func(self.view, selector, yellowView);
/*总结,需要的参数:
UIView;
backgroundColor = UIColor(yellowColor);
frame : {{100, 100}, {100, 100}}
self.view:addSubview(yellowView);
*/
三丶js调用oc
JSContext *context = [[JSContext alloc] init];
context[@"hello"] = ^(NSString *msg){
NSDictionary *creatClassDict = [msg dictionaryWithJsonString];
Class objClass = NSClassFromString(creatClassDict[@"class"]);
id yellowView = [[objClass alloc] init];
Class colorClass = NSClassFromString(creatClassDict[@"backgroundColor"][@"class"]);
SEL colorSelector = NSSelectorFromString(creatClassDict[@"backgroundColor"][@"value"]);
IMP colorImp = [colorClass methodForSelector:colorSelector];
id (*colorfunc)(id, SEL) = (void *)colorImp;
id color = colorfunc(colorClass, colorSelector);
[yellowView setValue:color forKey:creatClassDict[@"backgroundColor"][@"key"]];
[yellowView setValue:[NSValue valueWithCGRect:CGRectFromString(creatClassDict[@"frame"][@"value"])] forKey:creatClassDict[@"frame"][@"key"]];
SEL selector = NSSelectorFromString(creatClassDict[@"selector"]);
IMP imp = [self.view methodForSelector:selector];
void *(*func)(id, SEL, UIView *) =(void *) imp;
func(self.view, selector, yellowView);
NSLog(@"%@",creatClassDict);
};
[context evaluateScript:@"hello('{\"class\":\"UIView\",\"backgroundColor\":{\"key\":\"backgroundColor\",\"class\":\"UIColor\",\"value\":\"yellowColor\"},\"selector\":\"addSubview:\",\"frame\":{\"key\":\"frame\",\"value\":\"{{100, 100}, {100, 100}}\"}}')"];
指定js调用oc的规则,对实现的封装,就应该可以实现js调用oc;