详解Swift中 Sendable AnyActor Actor GlobalActor MainActor Task、await、async

详解Swift中 Sendable AnyActor Actor GlobalActor MainActor 的关联或者关系 及其 各自的作用 和 用法 以及与 Task、await、async:

  1. Sendable 协议
    作用:
    Sendable 是一个协议,它用于标记可以安全地跨线程或异步任务传递的数据类型。符合 Sendable 协议的类型可以在并发环境中被安全地传递,避免因数据竞争而产生的问题。

使用场景:
如果你希望将某个对象安全地传递给其他任务(如 Task),那么这个对象就必须符合 Sendable 协议。
在并发环境下,Swift 会确保 Sendable 类型的对象不会在多个线程之间产生数据竞争。
示例:

struct MyStruct: Sendable {var value: Int
}

在上面的例子中,MyStruct 遵循了 Sendable 协议,因此它可以被安全地传递给多个并发任务。

Sendable 与 Task、async、await 的关系:
Task 会在不同的并发上下文中执行。如果你需要将某些数据从一个任务传递到另一个任务中,这些数据就需要符合 Sendable 协议。
await 和 async 会创建异步任务,如果传递的数据不符合 Sendable,编译器会报错,提示数据类型不是可发送的。

  1. Actor 类型
    作用:
    Actor 是一种新的引用类型,专门用于确保在并发环境中的数据安全。Actor 通过序列化对其内部状态的访问来避免数据竞争。它通过自动同步访问来保证多线程环境中的线程安全。

使用场景:
Actor 主要用于封装需要在并发环境下访问的状态或数据,它确保数据不会被多个线程同时修改。
Actor 会保护其内部状态,所有对 Actor 内部数据的访问都会被序列化,因此可以避免数据竞态和不一致的状态。
示例:

actor Counter {private var value = 0func increment() {value += 1}func getValue() -> Int {return value}
}let counter = Counter()
Task {await counter.increment()let currentValue = await counter.getValue()print(currentValue)
}

Actor 与 Sendable 的关系:
Actor 本身是 线程安全 的,但如果 Actor 内部持有非 Sendable 类型的对象,它就不能跨线程或任务传递该对象。
如果你将 Actor 的实例作为任务的一部分进行传递,它需要符合 Sendable 协议,这意味着 Actor 中的所有状态和数据也需要是 Sendable 的。

  1. AnyActor 类型
    作用:
    AnyActor 是一个类型擦除的包装器,允许你将某个具体的 Actor 类型转为通用的 Actor 类型。它通常用于在无法预先知道具体 Actor 类型的场景中,或者当你需要在函数或方法中处理不同类型的 Actor 时。

使用场景:
当你需要处理多个不同类型的 Actor,并且无法在编译时确定具体的类型时,AnyActor 就非常有用。
示例:

actor MyActor {var value: Int = 0
}func performAction(actor: AnyActor) {// 对 AnyActor 做一些操作
}
  1. GlobalActor 协议
    作用:
    GlobalActor 是一个协议,它允许你为全局共享的并发环境(如主线程或后台线程)指定一个特定的执行上下文。通过 GlobalActor,你可以确保某些代码始终在特定的线程或调度队列上执行。

使用场景:
例如,MainActor 是一个 GlobalActor,它确保某些代码在 主线程 上执行,通常用于 UI 更新操作。
示例:

@globalActor
struct MainActor: GlobalActor {static let shared = MainActor()
}@MainActor
func updateUI() {// 此方法会在主线程上执行
}
  1. MainActor 类型
    作用:
    MainActor 是一个特殊的 GlobalActor,它确保标记的代码总是在主线程上执行。由于 UI 更新通常必须在主线程上进行,因此 MainActor 主要用于确保 UI 更新代码运行在主线程。

使用场景:
UI更新:在 SwiftUI 或 UIKit 中,需要确保界面更新代码运行在主线程,因此可以用 @MainActor 属性来标记这些方法。
示例:

@MainActor
func updateUI() {// 只有在主线程中执行print("UI is updated!")
}Task {await updateUI() // 确保在主线程执行
}

Task、async 和 await 与上述概念的关系
async 和 await:async 用于标记异步函数,await 用于等待异步函数的结果。在并发环境中,你可以通过 async 和 await 来执行任务,而不阻塞线程。

Task:Task 用于创建一个并发任务,它允许你在后台执行异步代码。你可以通过 Task 来启动异步代码并使用 await 来等待它的结果。

Actor 和 MainActor:当你在 Task 中使用 await 时,如果你的任务需要访问某个 Actor 类型的数据,确保你使用正确的并发上下文。例如,访问 UI 相关的状态时,要确保它在主线程上执行,可以使用 @MainActor 标记。

综合示例:

@MainActor
actor ViewModel {var data: String = "Hello"func updateData() {data = "Updated"print("Data updated on the main thread")}
}func performAsyncWork() async {let viewModel = ViewModel()await viewModel.updateData() // 在主线程执行
}Task {await performAsyncWork()
}

总结:
Sendable 是用于标记可以安全地传递的数据类型。
Actor 用于封装并发访问的对象,保证数据安全。
AnyActor 用于类型擦除,使得不同类型的 Actor 可以通用处理。
GlobalActor 和 MainActor 用于指定代码执行的全局并发上下文,确保代码在特定的线程上执行。
Task、async 和 await 用于创建和管理异步任务。

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

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

相关文章

使用VCS对Verilog/System Verilog进行单步调试的步骤

Verilog单步调试: System Verilog进行单步调试的步骤如下: 1. 编译设计 使用-debug_all或-debug_pp选项编译设计,生成调试信息。 我的4个文件: 1.led.v module led(input clk,input rst_n,output reg led );reg [7:0] cnt;alwa…

Kotlin 2.1.0 入门教程(十)if、when

if 表达式 if 是一个表达式&#xff0c;它会返回一个值。 不存在三元运算符&#xff08;condition ? then : else&#xff09;&#xff0c;因为 if 在这种场景下完全可以胜任。 var max aif (a < b) max bif (a > b) {max a } else {max b }max if (a > b) a…

数据结构及排序算法

数据结构 线性结构 ◆线性结构:每个元素最多只有一个出度和一个入度,表现为一条线状。线性表按存储方式分为顺序表和链表。 存储结构: ◆顺序存储:用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素物理上也相邻。 ◆链式存储:存储各数据元素的结点…

camera系统之cameraprovider

在相机系统中&#xff0c;CameraProvider是一个至关重要的组件。以下是对CameraProvider的详细解释&#xff1a; 一、定义与位置 CameraProvider是相机系统的下层组件&#xff0c;位于CameraService以下和Camera HAL&#xff08;硬件抽象层&#xff09;以上。它作为一个独立进…

python实现多路视频,多窗口播放功能

系列Python开发 文章目录 系列Python开发前言一、python实现多路视频播放功能二、代码实现1. http申请视频流地址并cv2播放功能 三、打包代码实现生成可执行文件 总结 前言 一、python实现多路视频播放功能 服务端开发后通常需要做功能测试、性能测试&#xff0c;通常postman、…

【R语言】数据操作

一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例&#xff1a; library("reshape2") View(tips) head()函数 查看前几行数据&…

51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤

一、Keil uVision5创建工程步骤 1.点击项目&#xff0c;新建 2.新建目录 3.选择目标机器&#xff0c;直接搜索at89c52选择&#xff0c;然后点击OK 4.是否添加起吊文件&#xff0c;一般选择否 5.再新建的项目工程中添加文件 6.选择C文件 7.在C文件中右键&#xff0c;添加…

STM32 软件SPI读写W25Q64

接线图 功能函数 //写SS函数 void My_W_SS(uint8_t BitValue) {GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue); }//写SCK函数 void My_W_SCK(uint8_t BitValue) {GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue); }//写MOSI函数 void My_W_MOSI(uint8_t Bit…

apachePoi中XSSFClientAnchor图片坐标简述;填充多张图片

概述 业务中经常会遇到在单元格内填充图片的需求&#xff0c;而且要求指定图片在单元格内的位置。 一般都是用的apache的poi&#xff0c;设置图片坐标。 HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)dx1 dy1 起始单元…

Centos挂载镜像制作本地yum源,并补装图形界面

内网环境centos7.9安装图形页面内网环境制作本地yum源 上传镜像到服务器目录 创建目录并挂载镜像 #创建目录 cd /mnt/ mkdir iso#挂载 mount -o loop ./CentOS-7-x86_64-DVD-2009.iso ./iso #前面镜像所在目录&#xff0c;后面所挂载得目录#检查 [rootlocalhost mnt]# df -h…

百科词条创建审核不通过的原因有哪些?

我们知道的国内有名的百科网站有百度百科、快懂百科、搜狗百科、360百科,这些有名的百科网站。一般来说,百科的词条排名都是在第一页的,无论是名人、明星、软件、影视名称,还是其他名称,大多排名都在首页,这就拥有了更多的曝光量和流量,而且由于百科是人们获取信息、查找资料的…

ssti学习笔记(服务器端模板注入)

目录 一&#xff0c;ssti是什么 二&#xff0c;原理 所谓模板引擎&#xff08;三列&#xff0c;可滑动查看&#xff09; 三&#xff0c;漏洞复现 1&#xff0c;如何判断其所属的模板引擎&#xff1f; 2&#xff0c;判断清楚后开始注入 &#xff08;1&#xff09;Jinja2&a…

【前端】Python 闭包与JavaScript闭包的实现差异

目录 Python 闭包JavaScript 闭包 推荐超级课程&#xff1a; Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战 Python 闭包 如何定义&#xff1a; 在一个函数内部定义另一个函数&#xff0c;内部函数引用外部函数的变量。 def outer_function(text):…

【JVM详解二】常量池

一、常量池概述 JVM的常量池主要有以下几种&#xff1a; class文件常量池运行时常量池字符串常量池基本类型包装类常量池 它们相互之间关系大致如下图所示&#xff1a; 每个 class 的字节码文件中都有一个常量池&#xff0c;里面是编译后即知的该 class 会用到的字面量与符号引…

人工智能入门 数学基础 线性代数 笔记

必备的数学知识是理解人工智能不可或缺的要素&#xff0c;今天的种种人工智能技术归根到底都建立在数学模型之上&#xff0c;而这些数学模型又都离不开线性代数&#xff08;linear algebra&#xff09;的理论框架。 线性代数的核心意义&#xff1a;世间万事万物都可以被抽象成某…

C# Winform怎么设计串口,客户端和相机控件界面显示

首先我们必须把这个类创建好 INIAPI using System; using System.Text; using System.Runtime.InteropServices;namespace Ini {public class IniAPI{#region INI文件操作/** 针对INI文件的API操作方法&#xff0c;其中的节点&#xff08;Section)、键&#xff08;KEY&#x…

【大数据技术】用户行为日志分析(python+hadoop+mapreduce+yarn+hive)

用户行为日志分析(python+hadoop+mapreduce+yarn+hive) 搭建完全分布式高可用大数据集群(VMware+CentOS+FinalShell) 搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn) 本机PyCharm远程连接虚拟机Python 搭建完全分布式高可用大数据集群(MySQL+Hive)

在 Windows 上使用 ZIP 包安装 MySQL 的详细步骤

以下是使用官方 ZIP 包在 Windows 上安装 MySQL 的详细步骤&#xff0c;确保能通过 mysql -uroot -p 成功连接。 步骤 1&#xff1a;下载 MySQL ZIP 包 访问 MySQL 官方下载页面&#xff1a; https://dev.mysql.com/downloads/mysql/选择 Windows (x86, 64-bit), ZIP Archive&…

前端学习-页面尺寸事件以及阻止默认行为(三十三)

目录 前言 页面尺寸事件 语法 检测屏幕宽度 获取宽高 元素尺寸的位置 总结 示例代码 阻止默认行为 阻止冒泡 语法 阻止冒泡如何做 阻止元素默认行为如何做 总结 前言 晚上好各位 页面尺寸事件 会在窗口尺寸改变的时候触发条件 语法 window.addEventListener(…

el-table表格点击单元格实现编辑

使用 el-table 和 el-table-column 创建表格。在单元格的默认插槽中&#xff0c;使用 div 显示文本内容&#xff0c;单击时触发编辑功能。使用 el-input 组件在单元格中显示编辑框。data() 方法中定义了 tableData&#xff0c;tabClickIndex: null,tabClickLabel: ,用于判断是否…