鸿蒙多线程开发——Sendable使用注意事项

1、概 述

本文是在鸿蒙多线程开发——线程间数据通信对象03(sendable)基础上做的扩展讨论。

Sendable协议定义了ArkTS的可共享对象体系及其规格约束。符合Sendable协议的数据(以下简称Sendable对象)可以在ArkTS并发实例间传递。

默认情况下,Sendable数据在ArkTS并发实例间(包括主线程、TaskPool、Worker线程)传递的行为是引用传递。同时,ArkTS也支持Sendable数据在ArkTS并发实例间拷贝传递。

Sendable的使用有一些需要注意的事项,本文针对较常见的情况做讨论。

2、Sendable的使用规则与约束

主要规则有:

  • Sendable class只能继承自Sendable class;

  • 非Sendable class只能继承自非Sendable class;

  • 非Sendable class只能实现非Sendable interface;

  • Sendable class/interface成员变量必须是Sendable支持的数据类型;

  • Sendable class/interface的成员变量不支持使用!断言;

  • Sendable class/interface的成员变量不支持使用计算属性名;

  • 泛型类中的Sendable class,collections.Array,collections.Map,collections.Set的模板类型必须是Sendable类型;

  • Sendable class的内部不允许使用当前模块内上下文环境中定义的变量;

  • Sendable class和Sendable function不能使用除了@Sendable的其它装饰器;

  • 不能使用对象字面量/数组字面量初始化Sendable类型;

  • 非Sendable类型不可以as成Sendable类型;

  • 箭头函数不支持共享;

  • Sendable装饰器修饰类型时仅支持修饰函数类型;

展开说明如下:

👉🏻 Sendable class只能继承自Sendable class

✅ 正确使用案例:

@Sendableclass A {  constructor() {  }}@Sendableclass B extends A {  constructor() {    super()  }}

❌ 错误使用案例:​​​​​​​

class A {  constructor() {  }}@Sendableclass B extends A {  constructor() {    super()  }}

👉🏻 非Sendable class只能继承自非Sendable class

✅ 正确使用案例:​​​​​​​

class A {  constructor() {  }}class B extends A {  constructor() {    super()  }}

❌ 错误使用案例:​​​​​​

@Sendableclass A {  constructor() {  }}class B extends A {  constructor() {    super()  }}

👉🏻 非Sendable class只能实现非Sendable interface

✅ 正确使用案例:​​​​​​​

interface I {};class B implements I {};

❌ 错误使用案例:​​​​​​​

import { lang } from '@kit.ArkTS';type ISendable = lang.ISendable;interface I extends ISendable {};class B implements I {};

👉🏻 Sendable class/interface成员变量必须是Sendable支持的数据类型

✅ 正确使用案例:​​​​​​​

@Sendableclass A {  constructor() {  }  a: number = 0;}

❌ 错误使用案例:​​​​​​​

@Sendableclass A {  constructor() {  }  b: Array<number> = [1, 2, 3] // 需使用collections.Array}

👉🏻 Sendable class/interface的成员变量不支持使用!断言

✅ 正确使用案例:​​​​​​​

@Sendableclass A {  constructor() {  }  a: number = 0;}

❌ 错误使用案例:​​​​​​​

@Sendableclass A {  constructor() {  }  a!: number;}

👉🏻 Sendable class/interface的成员变量不支持使用计算属性名

✅ 正确使用案例:​​​​​​​

@Sendableclass A {    num1: number = 1;    num2: number = 2;    add(): number {      return this.num1 + this.num2;    }}

❌ 错误使用案例:​​​​​​​

enum B {    b1 = "bbb"}@Sendableclass A {    ["aaa"]: number = 1; // ["aaa"] is allowed in other classes in ets files    [B.b1]: number = 2; // [B.b1] is allowed in other classes in ets files}

👉🏻 泛型类中的Sendable class,collections.Array,collections.Map,collections.Set的模板类型必须是Sendable类型

✅ 正确使用案例:​​​​​​​

import { collections } from '@kit.ArkTS';try {  let arr1: collections.Array<number> = new collections.Array<number>();  let num: number = 1;  arr1.push(num);} catch (e) {  console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);}

❌ 错误使用案例:​​​​​​​

import { collections } from '@kit.ArkTS';try {  let arr1: collections.Array<Array<number>> = new collections.Array<Array<number>>();  let arr2: Array<number> = new Array<number>();  arr2.push(1);  arr1.push(arr2);} catch (e) {  console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);}

👉🏻 Sendable class的内部不允许使用当前模块内上下文环境中定义的变量

由于Sendable对象在不同并发实例间的上下文环境不同,如果直接访问会有非预期行为。不支持Sendable对象使用当前模块内上下文环境中定义的变量,如果违反,编译阶段会报错。

✅ 正确使用案例:​​​​​​​

import { lang } from '@kit.ArkTS';type ISendable = lang.ISendable;interface I extends ISendable {}@Sendableclass B implements I {  static o: number = 1;  static bar(): B {    return new B();  }}@Sendableclass C {  v: I = new B();  u: number = B.o;  foo() {    return B.bar();  }}

❌ 错误使用案例:​​​​​​​

import { lang } from '@kit.ArkTS';type ISendable = lang.ISendable;interface I extends ISendable {}@Sendableclass B implements I {}function bar(): B {  return new B();}let b = new B();{  @Sendable  class A implements I {}  @Sendable  class C {    u: I = bar(); // bar不是sendable class对象,编译报错    v: I = new A(); // A不是定义在top level中,编译报错    foo() {      return b; // b不是sendable class对象,而是sendable class的实例,编译报错    }  }}

👉🏻 Sendable class和Sendable function不能使用除了@Sendable的其它装饰器

如果类装饰器定义在ts文件中,产生修改类的布局的行为,那么会造成运行时的错误。

✅ 正确使用案例:​​​​​​​

@Sendableclass A {  num: number = 1;}

❌ 错误使用案例:​​​​​​​

@Sendable@Observedclass C {  num: number = 1;}

👉🏻 不能使用对象字面量/数组字面量初始化Sendable类型

Sendable数据类型只能通过Sendable类型的new表达式创建。

✅ 正确使用案例:​​​​​​​

import { collections } from '@kit.ArkTS';let arr1: collections.Array<number> = new collections.Array<number>(1, 2, 3); // 是Sendable类型

❌ 错误使用案例:​​​​​​​

import { collections } from '@kit.ArkTS';let arr2: collections.Array<number> = [1, 2, 3]; // 不是Sendable类型,编译报错let arr3: number[] = [1, 2, 3]; // 不是Sendable类型,正例,不报错let arr4: number[] = new collections.Array<number>(1, 2, 3); // 编译报错

👉🏻 非Sendable类型不可以as成Sendable类型

✅ 正确使用案例:​​​​​​​

class A {  state: number = 0;}@Sendableclass SendableA {  state: number = 0;}let a1: A = new SendableA() as A;

❌ 错误使用案例:​​​​​​​

class A {  state: number = 0;}@Sendableclass SendableA {  state: number = 0;}let a2: SendableA = new A() as SendableA;

👉🏻 箭头函数不支持共享

✅ 正确使用案例:​​​​​​​

@Sendabletype SendableFuncType = () => void;@Sendablefunction SendableFunc() {  console.info("Sendable func");}@Sendableclass SendableClass {  constructor(f: SendableFuncType) {    this.func = f;  }  func: SendableFuncType;}let sendableClass = new SendableClass(SendableFunc);

❌ 错误使用案例:​​​​​​​

@Sendabletype SendableFuncType = () => void;let func: SendableFuncType = () => {}; // 编译报错@Sendableclass SendableClass {  func: SendableFuncType = () => {}; // 编译报错}

👉🏻 Sendable装饰器修饰类型时仅支持修饰函数类型

Sendable装饰器修饰类型时仅支持修饰函数类型。

✅ 正确使用案例:​​​​​​​

@Sendabletype SendableFuncType = () => void;

❌ 错误使用案例:​​​​​​​

@Sendabletype A = number; // 编译报错@Sendableclass C {}@Sendabletype D = C; // 编译报错

3、HAR中使用Sendable

在HAR中使用Sendable时,需开启编译生成TS文件的配置。

修改方式:在HAR模块下的module.json5文件中将"metadata"字段下的"name"设置为“UseTsHar”,配置如下所示:​​​​​​​

{  "module": {    "name": "TsClosedHar",    "type": "har",    "deviceTypes": [      "default",      "tablet",      "2in1"    ],    "metadata": [      {        "name": "UseTsHar",        "value": "true"      }    ]  }}

4、与TS/JS交互的规则

4.1、ArkTS通用规则(目前只针对Sendable对象)

  • Sendable对象传入TS/JS的接口中,禁止操作其对象布局(增、删属性,改变属性类型)。

  • Sendable对象设置到TS/JS的对象上,TS中获取到这个Sendable对象后,禁止操作其对象布局(增、删属性,改变属性类型)。

  • Sendable对象放入TS/JS的容器中,TS中获取到这个Sendable对象后,禁止操作其对象布局(增、删属性,改变属性类型)。

4.2、NAPI规则(目前只针对Sendable对象)

  • 禁止删除属性,不能使用的接口有:napi_delete_property。

  • 禁止新增属性,不能使用的接口有:napi_set_property、napi_set_named_property、napi_define_properties。

  • 禁止修改属性类型,不能使用的接口有:napi_set_property、napi_set_named_property、napi_define_properties。

  • 不支持Symbol相关接口和类型,不能使用的接口有:napi_create_symbol、napi_is_symbol_object、napi_symbol。

5、与UI交互的规则

Sendable数据需要与makeObserved联用,才可以观察Sendable对象的数据变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/61756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1074 Reversing Linked List (25)

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K3, then you must output 3→2→1→6→5→4; if K4, you must output 4→3→2→1→5→6. Input Specif…

Wwise SoundBanks内存优化

1.更换音频格式为Vorbis 2.停用多余的音频&#xff0c;如Random Container的随机脚步声数量降为2个 3.背景音乐勾选“Stream”。这样就让音频从硬盘流送到Wwise&#xff0c;而不是保存在内存当中&#xff0c;也就节省了内存 4.设置最大发声数Max Voice Instances 5.设置音频…

产品转后端?2

产品经理的视角能让你成为更好的后端工程师&#xff1a; 理解业务需求转换为技术方案的过程知道为什么要这样设计API明白数据结构的选择如何影响用户体验了解性能指标对业务的实际影响 在实习过程中可以有意识地向后端倾斜&#xff1a; 常规产品经理工作&#xff1a; "…

C 语言 “神秘魔杖”—— 指针初相识,解锁编程魔法大门(一)

文章目录 一、概念1、取地址操作符&#xff08;&&#xff09;2、解引用操作符&#xff08;*&#xff09;3、指针变量1、 声明和初始化2、 用途 二、内存和地址三、指针变量类型的意义1、 指针变量类型的基本含义2、 举例说明不同类型指针变量的意义 四、const修饰指针1、co…

Android 使用OpenGLES + MediaPlayer 获取视频截图

概述 Android 获取视频缩略图的方法通常有: ContentResolver: 使用系统数据库MediaMetadataRetriever: 这个是android提供的类&#xff0c;用来获取本地和网络media相关文件的信息ThumbnailUtils: 是在android2.2&#xff08;api8&#xff09;之后新增的一个&#xff0c;该类为…

博泽Brose EDI项目案例

Brose 是一家德国的全球性汽车零部件供应商&#xff0c;主要为全球汽车制造商提供机电一体化系统和组件&#xff0c;涵盖车门、座椅调节系统、空调系统以及电动驱动装置等。Brose 以其高质量的创新产品闻名&#xff0c;在全球拥有多个研发和生产基地&#xff0c;是全球第五大家…

python使用python-docx处理word

文章目录 一、python-docx简介二、基本使用1、新建与保存word2、写入Word&#xff08;1&#xff09;打开文档&#xff08;2&#xff09;添加标题&#xff08;3&#xff09;添加段落&#xff08;4&#xff09;添加文字块&#xff08;5&#xff09;添加图片&#xff08;6&#xf…

aws(学习笔记第十五课) 如何从灾难中恢复(recover)

aws(学习笔记第十五课) 如何从灾难中恢复 学习内容&#xff1a; 使用CloudWatch对服务器进行监视与恢复区域(region)&#xff0c;可用区(available zone)和子网(subnet)使用自动扩展(AutoScalingGroup) 1. 使用CloudWatch对服务器进行监视与恢复 整体架构 这里模拟Jenkins Se…

lwip raw、netcoon、socket三种接口编程的区别

目录 一、前言 二、LWIP 简介 三、LWIP RAW 编程 1.概念与原理 2.编程模型与流程 3.示例代码 4.优点与缺点 四、LWIP NETCONN 编程 1.概念与原理 2.编程模型与流程 3.示例代码 4.优点与缺点 五、LWIP SOCKET 编程 1.概念与原理 2.编程模型与流程 3.示例代码 …

软件设计 —— 检测按键单击、多击、长按或组合动作

目 录 按键单一动作识别按键组合动作识别 按键单一动作识别 带有按键的作品设计时&#xff0c;按键动作检测是必不可少的&#xff0c;如何判断按键是单击、双击、三击和长按动作呢&#xff1f; 1、定时器定时一个10ms周期 2、把按键检测函数放到这个周期内执行&#xff0c;即…

MySQL MVCC 介绍

MVCC&#xff08;Multi-Version Concurrency Control&#xff09;是一种并发控制机制&#xff0c;用于在多个并发事务同时读写数据库时保持数据的一致性和隔离性。MVCC通过在每个数据行上维护多个版本的数据来实现。当一个事务要对数据库中的数据进行修改时&#xff0c;MVCC不会…

【XGlassTerminal.js】快速 构建 炫酷 终端 网页 以及 Linux 模拟器 在线!!

XGlassTerminal.js XGlassTerminal.js 是一个用于构建前端终端样式的 JavaScript 库。它允许开发者轻松地创建一个具有终端风格的用户界面&#xff0c;并对用户输入的命令进行事件处理。 该库提供了丰富的功能&#xff0c;包括文本添加、命令处理、点击事件绑定等。 同时还支…

车辆传动系统的simulink建模与仿真,分析加速和刹车两个工况

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 车辆传动系统的simulink建模与仿真,分析加速和刹车两个工况。模型包括车辆模块&#xff0c;传动模块&#xff0c;发动机模块&#xff0c;换挡模块&#xff0c;刹车油门输入模块…

MySQL如何区分幻读和不可重复读

在MySQL中&#xff0c;幻读和不可重复读都是并发事务中可能出现的问题&#xff0c;但它们的表现和原因略有不同。 不可重复读 (Non-Repeatable Read) 不可重复读是指在同一个事务内&#xff0c;多次读取同一行数据时&#xff0c;可能会得到不同的结果。这种情况发生在一个事务…

宝塔配置定时任务详解

文章目录 宝塔配置定时任务详解一、引言二、配置定时任务1、登录宝塔面板2、添加定时任务2.1、步骤 3、配置任务3.1、设置任务名称和执行周期3.2、设置执行命令 4、保存并测试 三、使用示例1、备份数据库2、清理日志文件 四、总结 宝塔配置定时任务详解 一、引言 在服务器管理…

【C++笔记】map和set的使用

【C笔记】map和set的深度剖析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】map和set的深度剖析前言一.set1.1 序列式容器和关联式容器1.2 set系列的使用1.3 set类的介绍1.4 set的构造和迭代器1.5 set的增删查1.6…

springboot+mybatis对接使用postgresql中PostGIS地图坐标扩展类型字段

方案一&#xff08;完全集成和自动解析&#xff09;&#xff1a; <dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId></dependency> 使用 org.postgresql.geometric包下的 PGpoint 类来接收数据库中POINT…

《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?“找不到mfc140u.dll文件”要怎么解决?教你几招轻松搞定

《只狼》运行时提示“mfc140u.dll文件缺失”的科普与解决方案 作为一名软件开发从业者&#xff0c;在游戏开发和维护过程中&#xff0c;我们经常会遇到各种运行时错误和系统报错。今天&#xff0c;我们就来探讨一下《只狼》这款游戏在运行时提示“mfc140u.dll文件缺失”的原因…

华为HarmonyOS 让应用快速拥有账号能力 -- 3 获取用户手机号

场景介绍 当应用对获取的手机号时效性要求不高时&#xff0c;可使用Account Kit提供的手机号授权与快速验证能力&#xff0c;向用户发起手机号授权申请&#xff0c;经用户同意授权后&#xff0c;获取到手机号并为用户提供相应服务。以下只针对Account kit提供的手机号授权与快…

shodan(3)

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…