JSPatch学习笔记

简单记录一下学习心得,比较乱,后年完善
JSPatch 学习笔记

1.文件加载
首先,将要替换的JS文本进行正则替换,将所有的.替换成_ _ c 方法,这样,JSPatch中加载的JS文件执行.操作后就变成了执行__c方法,执行这个方法后会中转到__OC_call 方法中。
例子: var tableViewCtrl = JPTableViewController.__c("alloc")().__c("init")()
self.__c("navigationController")().__c("pushViewController_animated")(tableViewCtrl, YES)
}

2.消息转发
static void JPForwardInvocation(__unsafe_unretained id assignSlf, SEL selector, NSInvocation *invocation)
解析:
OC 调用JS的方法,通过消息转发。将要替换的方法绑定到__forwarding方法上,这样被替换的OC方法在执行的时候走forwardingInvoke方法,通过invocation获取到所有的OC函数,通过JPBox包装一下后,将self包装成JPBox对象,如果是NSNuber,则可以转成NSSString,或者直接用NSNumber,调用JS函数时系统会对基本类型做桥接转换,转换成JS对应的Number、String。对于其他对象,则 对象转换成字典,其中,__obj一般存放JPBox对象,__className存放对象的类信息。 @{@"__obj": obj, @"__clsName": NSStringFromClass([obj isKindOfClass:[JPBoxing class]] ? [[((JPBoxing *)obj) unbox] class]: [obj class])},获取到所有的参数列表后,
通过 [invocation getArgument:&arg atIndex:i]; 回去到对应位置的参数。
执行JS方法[jsFunc callWithArguments:params];获得到返回值的时候执行formatJSToOC方法,将JS字典转换成OC对象,然后给invocation设置返回值
[invocation setReturnValue:&ret];执行结束,******,因为不是要执行,
方法转发的时候,主要是获取参数getArgument: 和设置返回值returnValue。
所以不用调用[[invocation invoke]函数,invoke的目的是执行...
var tableViewCtrl = JPTableViewController.__c("alloc")().__c("init")()
self.__c("navigationController")().__c("pushViewController_animated")(tableViewCtrl, YES)
}
在defineClass中定义了全局的对象gloabel["JPTableViewController"],这样JPTableViewController其实是个JS变量的名字,对应的是一个JS字典。

3.函数调用(JS侧调用OC方法)
static id callSelector(NSString *className, NSString *selectorName, JSValue *arguments, JSValue *instance, BOOL isSuper)
相对应,此方法是JS通过.方法调用(其实是执行了__c函数),这样会携带JS的参数来调用OC的函数,将JS的参数解包成OC的函数,
instance = formatJSToOC(instance)
invocation= [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:cls];
//将JS的参数解析成OC中的对象类型
[invocation setArgument:&value atIndex:i];
//OC方法执行
[invocation invoke];
//从执行的方法中获取返回值
[invocation getReturnValue:&result];
//OC对象放回对象包装成JS对象,供JS使用。
return formatOCToJS(returnValue);

encode对应的类型
JP_FWD_ARG_CASE('c', char)
JP_FWD_ARG_CASE('C', unsigned char)
JP_FWD_ARG_CASE('s', short)
JP_FWD_ARG_CASE('S', unsigned short)
JP_FWD_ARG_CASE('i', int)
JP_FWD_ARG_CASE('I', unsigned int)
JP_FWD_ARG_CASE('l', long)
JP_FWD_ARG_CASE('L', unsigned long)
JP_FWD_ARG_CASE('q', long long)
JP_FWD_ARG_CASE('Q', unsigned long long)
JP_FWD_ARG_CASE('f', float)
JP_FWD_ARG_CASE('d', double)
JP_FWD_ARG_CASE('B', BOOL)
'{':是结构体
':': 是selector
^ * 是C指针

对应Class

@ 是 对象
@? 是block

你可能感兴趣的:(JSPatch学习笔记)