JavaScriptCore
jsc 其实就是苹果 Safari 浏览器的 javascript 引擎, 主要负责 OC 与 JS 之间的交互
OC 与 JS 交互(OC 调用 JS 代码)
这是一段简单的代码 上面 import了 JSC 的框架, 然后创建了一个 JSContext 的对象, 然后用 context 执行了一段 js代码, 执行后得到了一个 jsValue 类型的值, 最后将这个值转换为整型并输出, 这样就完成了 OC 调用一段 JS 代码
这里有两个对象需要注意:
JSContext: JSContext 是 js 代码的执行环境为 JS 代码的执行提供了上下文环境, 通过 JSCore 执行的 JS 代码都得通过 JSContext 来执行
JSContext 对应于 JS 中的一个全局对象,相当于浏览器的 window 对象. JSContext 中有一个 GlobalObject 属性, 实际上 JS代码都是在这个 GlobalObject 上执行的
JSValue: 是对 js 值的包装,对应于 OC 中的类型, jsValue 是不能独立存在的.必须存在于 JSContext 中
JSValue 对应的 JS 值和所处的 JSContext 对象都是强引用关系, 因为JSValue 需要这两个东西来执行 JS 代码, 所以 JSValue 会一直持有他们
JS与 OC 的交互
Block: 就是在传递给 js的方法里暴露一个block给 js 调用
// 在 OC 里 把一个 block 注入 JSContext
// 在 js里调用 jsCore 会自动在全局对象中创建一个 makeNSColor 的函数, 将这个 block 包装起来
// JSExport协议
通过 JSExport 协议可以很方便的将 OC 中的对象暴露给 JS 调用, 且在 JS 中使用起来就像 JS 对象一样
他的属性可以直接调用像 js 一样, 实例方法可以直接调用
实现这些只需写一句话 @protocal MyPointExports <JSExport>
他的本质就是把 OC 类的属性和实例方法 类方法添加都 JS 的原型链上
Tips: // 内存管理方面
不要在 JS 中给OC 对象增加成员变量 因为在 JS 中增加在 OC 中并不会同步增加
OC 中不要直接强引用 JSValue 对象 不要将一个 JSValue对象当属性或者成员变量, 当这个 OC 对象暴露给 JS 的时候会造成循环引用, 因为前面说过 JSValue对 JSContext 是强引用的
苹果推出了一种新的引用关系 有条件的强引用 苹果使用 JSManagedValue 来包着一个 JSValue 对象就可以
// 线程方面
JSVirtualMachine 他为 js的运行提供了底层资源, 有自己的堆栈和垃圾回收机制
JSVirtualMachine还是 JSContext 的容器 可以包含若干个 JSContext, 在一个进程可以有多个JSVirtualMachine, 里面包含若干个 JSContext, 而 JSContext 中又有若干个 JSValue, 需要注意的是可以在同一个 JSVirtualMachine的不同 JSContext 中互相传递 JSValue ,但是不能再不同的JSVirtualMachine中的 JSContext 之间传递 JSValue