javaScriptCore(jsCore)、webKit、jsvm、jsContext 笔记
https://www.cnblogs.com/meituantech/p/9528285.html
1、JS的内存管理使用的是GC机制(Tracing Garbage Collection)
不同于Java的OC的引用计数,Tracing Garbage Collection是由GCRoot(Context)开始维护的一条引用链,一旦引用链无法触达某对象节点,这个对象就会被回收掉。
2、JS中所谓的全局变量,全局函数不过是全局对象的属性和函数。
通过KVC的方式,给JSContext塞进去很多全局对象或者全局函数,这样执行上下文中就可以直接使用这些对象或者函数,存在于最高层作用域,实际就是绑在了执行上下文上。
在JSContext的API中,有一个值得注意的只读属性 -- JSValue类型的globalObject。它返回当前执行JSContext的全局对象,例如在WebKit中,JSContext就会返回当前的Window对象。而这个全局对象其实也是JSContext最核心的东西,当我们通过KVC方式与JSContext进去取值赋值的时候,实际上都是在跟这个全局对象做交互,几乎所有的东西都在全局对象里,可以说,JSContext只是globalObject的一层壳
3、以通过KVC的方式获取当时WebView的JSContext
每个JSValue都存在于一个JSContext之中,这也就是JSValue的作用域
4、JSValue属于JSContext,从属关系,一一对应
我们可以很简单的通过KVC操作JS全局对象,也可以直接获得JS代码执行结果的返回值(同时每一个JS中的值都存在于一个执行环境之中,也就是说每个JSValue都存在于一个JSContext之中,这也就是JSValue的作用域),都是因为JSCore帮我们用JSValue在底层自动做了OC和JS的类型转换。
5、JSContext和JSVM是多对一的关系:
每个JSContext都从属于一个JSVM。我们可以通过JSContext的只读属性 -- virtualMachine获得当前JSContext绑定的JSVM。JSContext和JSVM是多对一的关系,一个JSContext只能绑定一个JSVM,但是一个JSVM可以同时持有多个JSContext。而上文中我们提到,每个JSVM同时只有整个一个线程来执行JS代码
6、JSExport:实现JSExport协议可以开放OC类和它们的实例方法,类方法,以及属性给JS调用。
7、JSPatch的对象和方法没有实现JSExport协议,JS是如何调OC方法的?
JSPatch另辟蹊径,使用了OC的Runtime消息转发机制做这个事情。借助JSCore的Context与JSCore的类型转换和OC的消息转发机制来完成动态调用,实现思路真的很巧妙。
8、桥方法的实现是怎么通过JSCore交互的?
市面上常见的桥方法调用有两种:
-
通过UIWebView的delegate方法:shouldStartLoadWithRequest来处理桥接JS请求。JSRequest会带上methodName,通过WebViewBridge类调用该method。执行完之后,会使用WebView来执行JS的回调方法,当然实际上也是调用的WebView中的JSContext来执行JS,完成整个调用回调流程。
-
通过UIWebView的delegate方法:在webViewDidFinishLoadwebViewDidFinishLoad里通过KVC的方式获取UIWebView的JSContext,然后通过这个JSContext设置已经准备好的桥方法供JS环境调用。