当前位置: 首页 > news >正文

有没有电脑做兼职的网站好看的网站ui

有没有电脑做兼职的网站,好看的网站ui,关于 公司网站建设的通知,网站制作多少当传入napi_get_cb_info的argv不为nullptr时,argv的长度必须大于等于传入argc声明的大小。 当argv不为nullptr时,napi_get_cb_info会根据argc声明的数量将JS实际传入的参数写入argv。如果argc小于等于实际JS传入参数的数量,该接口仅会将声明…

当传入napi_get_cb_info的argv不为nullptr时,argv的长度必须大于等于传入argc声明的大小。

当argv不为nullptr时,napi_get_cb_info会根据argc声明的数量将JS实际传入的参数写入argv。如果argc小于等于实际JS传入参数的数量,该接口仅会将声明的argc数量的参数写入argv;而当argc大于实际参数数量时,该接口会在argv的尾部填充undefined。

错误示例

static napi_value IncorrectDemo1(napi_env env, napi_callbackk_info info) {// argc 未正确的初始化,其值为不确定的随机值,导致 argv 的长度可能小于 argc 声明的数量,数据越界。size_t argc;napi_value argv[10] = {nullptr};napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);return nullptr;
}static napi_value IncorrectDemo2(napi_env env, napi_callback_info info) {// argc 声明的数量大与 argv 实际初始化的长度,导致 napi_get_cb_info 接口在写入 argv 时数据越界。size_t argc = 5;napi_value argv[3] = {nullptr};napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);return nullptr;
}

正确示例

static napi_value GetArgvDemo1(napi_env env, napi_callback_info info) {size_t argc = 0;// argv 传入 nullptr 来获取传入参数真实数量napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);// JS 传入参数为0,不执行后续逻辑if (argc == 0) {return nullptr;}// 创建数组用以获取JS传入的参数napi_value* argv = new napi_value[argc]; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);// 业务代码// ... ...// argv 为 new 创建的对象,在使用完成后手动释放delete argv;return nullptr;
}static napi_value GetArgvDemo2(napi_env env, napi_callback_info info) {size_t argc = 2;napi_value* argv[2] = {nullptr}; // napi_get_cb_info 会向 argv 中写入 argc 个 JS 传入参数或 undefinednapi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);// 业务代码// ... ...return nullptr;
}

生命周期管理

【规则】 合理使用napi_open_handle_scope和napi_close_handle_scope管理napi_value的生命周期,做到生命周期最小化,避免发生内存泄漏问题。

每个napi_value属于特定的HandleScope,HandleScope通过napi_open_handle_scope和napi_close_handle_scope来建立和关闭,HandleScope关闭后,所属的napi_value就会自动释放。

正确示例

// 在for循环中频繁调用napi接口创建js对象时,要加handle_scope及时释放不再使用的资源。 
// 下面例子中,每次循环结束局部变量res的生命周期已结束,因此加scope及时释放其持有的js对象,防止内存泄漏
for (int i = 0; i < 100000; i++) { napi_handle_scope scope = nullptr;   napi_open_handle_scope(env, &scope); if (scope == nullptr) { return; } napi_value res; napi_create_object(env, &res); napi_close_handle_scope(env, scope); 
}

上下文敏感

【规则】 多引擎实例场景下,禁止通过Node-API跨引擎实例访问JS对象。

引擎实例是一个独立运行环境,JS对象创建访问等操作必须在同一个引擎实例中进行。若在不同引擎实例中操作同一个对象,可能会引发程序崩溃。引擎实例在接口中体现为napi_env。

错误示例

// 线程1执行,在env1创建string对象,值为"bar"、 
napi_create_string_utf8(env1, "bar", NAPI_AUTO_LENGTH, &string);
// 线程2执行,在env2创建object对象,并将上述的string对象设置到object对象中
napi_status status = napi_create_object(env2, &object); 
if (status != napi_ok) { napi_throw_error(env, ...); return; 
} status = napi_set_named_property(env2, object, "foo", string); 
if (status != napi_ok) { napi_throw_error(env, ...); return; 
}

所有的JS对象都隶属于具体的某一napi_env,不可将env1的对象,设置到env2中的对象中。在env2中一旦访问到env1的对象,程序可能会发生崩溃。

异常处理

【建议】 Node-API接口调用发生异常需要及时处理,不能遗漏异常到后续逻辑,否则程序可能发生不可预期行为。

正确示例

// 1.创建对象
napi_status status = napi_create_object(env, &object); 
if (status != napi_ok) { napi_throw_error(env, ...); return;
} 
// 2.创建属性值 
status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string); 
if (status != napi_ok) { napi_throw_error(env, ...); return; 
} 
// 3.将步骤2的结果设置为对象object属性foo的值 
status = napi_set_named_property(env, object, "foo", string); 
if (status != napi_ok) { napi_throw_error(env, ...); return; 
}

如上示例中,步骤1或者步骤2出现异常时,步骤3都不会正常进行。只有当方法的返回值是napi_ok时,才能保持继续正常运行;否则后续流程可能会出现不可预期的行为。

异步任务

【规则】 当使用uv_queue_work方法将任务抛到JS线程上面执行的时候,对JS线程的回调方法,一般情况下需要加上napi_handle_scope来管理回调方法创建的napi_value的生命周期。

使用uv_queue_work方法,不会走Node-API框架,此时需要开发者自己合理使用napi_handle_scope来管理napi_value的生命周期。

正确示例

void callbackTest(CallbackContext* context) 
{ uv_loop_s* loop = nullptr; napi_get_uv_event_loop(context->env, &loop); uv_work_t* work = new uv_work_t; context->retData = 1; work->data = (void*)context; uv_queue_work( loop, work, [](uv_work_t* work) {}, // using callback function back to JS thread [](uv_work_t* work, int status) { CallbackContext* context = (CallbackContext*)work->data; napi_handle_scope scope = nullptr; napi_open_handle_scope(context->env, &scope); if (scope == nullptr) { return; } napi_value callback = nullptr; napi_get_reference_value(context->env, context->callbackRef, &callback); napi_value retArg; napi_create_int32(context->env, context->retData, &retArg); napi_value ret; napi_call_function(context->env, nullptr, callback, 1, &retArg, &ret); napi_delete_reference(context->env, context->callbackRef); napi_close_handle_scope(context->env, scope); if (work != nullptr) { delete work; } delete context; } ); 
}

对象绑定

【规则】 使用napi_wrap接口,如果最后一个参数result传递不为nullptr,需要开发者在合适的时机调用napi_remove_wrap函数主动删除创建的napi_ref。

napi_wrap接口定义如下:

napi_wrap(napi_env env, napi_value js_object, void* native_object, napi_finalize finalize_cb, void* finalize_hint, napi_ref* result)

当最后一个参数result不为空时,框架会创建一个napi_ref对象,指向js_object。此时开发者需要自己管理js_object的生命周期,即需要在合适的时机调用napi_remove_wrap删除napi_ref,这样GC才能正常释放js_object,从而触发绑定C++对象native_object的析构函数finalize_cb。

一般情况下,根据业务情况最后一个参数result可以直接传递为nullptr。

正确示例

// 用法1:napi_wrap不需要接收创建的napi_ref,最后一个参数传递nullptr,创建的napi_ref是弱引用,由系统管理,不需要用户手动释放 
napi_wrap(env, jsobject, nativeObject, cb, nullptr, nullptr); // 用法2:napi_wrap需要接收创建的napi_ref,最后一个参数不为nullptr,返回的napi_ref是强引用,需要用户手动释放,否则会内存泄漏 
napi_ref result; 
napi_wrap(env, jsobject, nativeObject, cb, nullptr, &result); 
// 当js_object和result后续不再使用时,及时调用napi_remove_wrap释放result 
napi_value result1; 
napi_remove_wrap(env, jsobject, result1);

高性能数组

【建议】 存储值类型数据时,使用ArrayBuffer代替JSArray来提高应用性能。

使用JSArray作为容器储存数据,支持几乎所有的JS数据类型。

使用napi_set_element方法对JSArray存储值类型数据(如int32)时,同样会涉及到与运行时的交互,造成不必要的开销。

ArrayBuffer进行增改是直接对缓冲区进行更改,具有远优于使用napi_set_element操作JSArray的性能表现。

因此此种场景下,更推荐使用napi_create_arraybuffer接口创建的ArrayBuffer对象。

示例:

// 以下代码使用常规JSArray作为容器,但其仅存储int32类型数据。
// 但因为是JS对象,因此只能使用napi方法对其进行增改,性能较低。
static napi_value ArrayDemo(napi_env env, napi_callback_info info)
{constexpr size_t arrSize = 1000;napi_value jsArr = nullptr;napi_create_array(env, &jsArr);for (int i = 0; i < arrSize; i++) {napi_value arrValue = nullptr;napi_create_int32(env, i, &arrValue);// 常规JSArray使用napi方法对array进行读写,性能较差。napi_set_element(env, jsArr, i, arrValue);}return jsArr;
}// 推荐写法:
// 同样以int32类型数据为例,但以下代码使用ArrayBuffer作为容器。
// 因此可以使用C/C++的方法直接对缓冲区进行增改。
static napi_value ArrayBufferDemo(napi_env env, napi_callback_info info)
{constexpr size_t arrSize = 1000;napi_value arrBuffer = nullptr;void* data = nullptr;napi_create_arraybuffer(env, arrSize * sizeof(int32_t), &data, &arrBuffer);int32_t* i32Buffer = reinterpret_cast<int32_t*>(data);for (int i = 0; i < arrSize; i++) {// arrayBuffer直接对缓冲区进行修改,跳过运行时,// 与操作原生C/C++对象性能相当i32Buffer[i] = i;}return arrBuffer;
}

napi_create_arraybuffer等同于JS代码中的new ArrayBuffer(size),其生成的对象不可直接在TS/JS中进行读取,需要将其包装为TyppedArray或DataView后方可进行读写。

基准性能测试结果如下:

说明: 以下数据为千次循环写入累计数据,为更好的体现出差异,已对设备核心频率进行限制。

容器类型Benchmark数据(us)
JSArray1566.174
ArrayBuffer3.609

数据转换

【建议】 尽可能的减少数据转换次数,避免不必要的复制。

  • 减少数据转换次数: 频繁的数据转换可能会导致性能下降,可以通过批量处理数据或者使用更高效的数据结构来优化性能;
  • 避免不必要的数据复制: 在进行数据转换时,可以使用Node-API提供的接口来直接访问原始数据,而不是创建新的副本;
  • 使用缓存: 如果某些数据在多次转换中都会被使用到,可以考虑使用缓存来避免重复的数据转换。缓存可以减少不必要的计算,提高性能。

其它

【规则】 使用napi_get_arraybuffer_info接口,第三个参数data资源开发者不允许释放,data的生命周期受引擎管理。

napi_get_arraybuffer_info接口定义如下:

napi_get_arraybuffer_info(napi_env env, napi_value arraybuffer, void** data, size_t* byte_length)

data获取的是ArrayBuffer的Buffer头指针,开发者只可以在范围内读写该Buffer区域,不可以进行释放操作。该段内存由引擎内部的ArrayBuffer Allocator管理,随JS对象ArrayBuffer的生命周期释放。

错误示例:

void* arrayBufferPtr = nullptr;
napi_value arrayBuffer = nullptr;
size_t createBufferSize = ARRAY_BUFFER_SIZE;
napi_status verification = napi_create_arraybuffer(env, createBufferSize, &arrayBufferPtr, &arrayBuffer);
size_t arrayBufferSize;
napi_status result = napi_get_arraybuffer_info(env, arrayBuffer, &arrayBufferPtr, &arrayBufferSize);
delete arrayBufferPtr; // 这一步是禁止的,创建的arrayBufferPtr生命周期由引擎管理,不允许用户自己delete,否则会double free

【建议】 合理使用napi_object_freeze和napi_object_seal来控制对象以及对象属性的可变性。

napi_object_freeze等同于Object.freeze语义,freeze后对象的所有属性都不可能以任何方式被修改;napi_object_seal等同于Object.seal语义,对象不可增删属性。两者的主要区别是,freeze不能改属性的值,seal还可以改属性的值。

开发者使用以上语义时,需确保约束条件是自己需要的,一旦违背以上语义严格模式下就会抛出Error(默认严格模式)。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

http://www.yidumall.com/news/13331.html

相关文章:

  • 简单个人网站制作教程站内推广的方法和工具
  • 原创婚纱摄影浙江搜索引擎优化
  • 哈尔滨仿站定制模板建站发稿
  • 海口网站建设 海南小黄网络关键词优化心得
  • 在国内做博彩网站代理爱网站关键词挖掘
  • 有没有免费的室内设计软件深圳seo网络推广
  • 做网站定位全网关键词搜索
  • 广汉网站建设5000元网站seo推广
  • 网站建设价格标准信息百度推广账号怎么注册
  • 长春专业企业网站建设价格关键词优化怎么优化
  • 个人网站多少钱搜索引擎优化哪些方面
  • 路由器建wordpress伟哥seo博客
  • 漫画网站做任务给金币2345网址导航浏览器
  • wap网站 微信现在广告行业好做吗
  • 网站首页不见怎么做海外营销方案
  • 北京市住房和城乡建设部官方网站成品app直播源码有什么用
  • 在国外做电商网站有哪些seo的研究对象
  • 门户网站建设目标网站一年了百度不收录
  • 火星免费建网站原画培训班一般学费多少
  • wordpress文章投稿优化大师
  • 加强网站建设 通知全网营销系统是干什么的
  • 衢州网站制作2023年12月疫情又开始了吗
  • 网站说服力 营销...巧克力软文范例200字
  • 做企业网站需要服务器么网站seo软件
  • 重庆网站seo多少钱百度网站提交了多久收录
  • 免费元素素材网站联盟营销平台
  • 做 耽美小说下载网站有哪些软文写作是什么意思
  • 网站小样用什么做成都纯手工seo
  • javaweb做的网站有哪些招商外包公司
  • 揭阳做网站公司湖南seo网站开发