JSI 值活在 JS 引擎的堆上。轻量设备这块堆不大,模块又经常一次返回十几个字段,只创建不释放,很快就会把堆顶满。所以值的生命周期必须显式管理,不能按普通 C++ 局部变量来想。


可以先记三条。第一,谁创建或取出,谁释放。创建对象、字符串、数字,以及按名字取出的属性,用完都要释放。从值里拷出来的 C 字符串,走字符串专用的释放接口,不要和值释放混用。第二,返回给 JS 的那一个值不要提前放。函数里组装好的结果对象交给框架,由框架决定何时交给脚本、何时回收。第三,要跨多次调用存活的值,必须先取得引用。页面注册的回调最典型:参数里的函数只在当次调用有效,想在之后的系统事件里再调它,就要取得引用并保存;页面销毁或取消监听时再成对释放。漏掉释放是泄漏,重复释放或用已释放的句柄则是更难查的异常。


组装返回对象时,习惯写法是:先创建一个对象,再为每个字段准备临时值、挂到对象上,然后立刻释放临时值,只留下结果对象作为返回。从 JS 对象读字段也一样,取出、用完、释放。多个临时值可以一次性收尾,减少漏释放。类型必须先判断再转换:先确认是数字、字符串、布尔、对象还是函数,再取值。空值和未定义要有明确分支,不要默认当成合法对象。


回调还要处理「换人」的问题。用户重新注册监听时,旧引用要先丢掉,并区分事件属于哪一次注册,避免把过期通知交给新回调。JSI 不管字段代表什么业务,只保证句柄不泄漏、类型不误用。Native 模块稳不稳,往往比分支逻辑更取决于这套规则有没有写全。

JSIValue obj = JSI::CreateObject();
JSI::SetNumberProperty(obj, "code", 0);
JSI::ReleaseValue(temp); // 临时值用完即放,obj 作为返回值留

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐