Swift 中 @preconcurrency 修饰符使用浅谈

在这里插入图片描述

概述

Swift 6.0 与我们越来越近了,如何将旧范儿的并发代码装换为严格遵守 Swift 6.0 并发模型( Strict Concurrency)的新代码,这往往使得秃头码农们又要多抓掉几根头发了。

在这里插入图片描述

所以,为了最大限度的保持新旧两个并发世界暂时的“和平共处”,苹果特地推出了 @preconcurrency 修饰符让我们能得以优雅的“樽前月下”。

在本篇博文中,您将学到如下内容:

  • 概述
  • 1. @preconcurrency 是干啥用的?
  • 2. 导入中的 @preconcurrency
  • 3. 类型修饰中的 @preconcurrency
  • 4. 一些使用提示
  • 总结

闲言少叙,让我们马上开始 Swift 并发大冒险吧!

Let‘s go!!!😉


1. @preconcurrency 是干啥用的?

从 Swift 5.6(正式支持 @preconcurrency 的第一个 Swift 编译器版本)开始,苹果为 Swift 语言引入了@preconcurrency 修饰符。

当项目使用严格并发检查模式(strict concurrency checks)时我们可以使用它来让大量产生的编译器警告和错误“通通闭嘴”。

在这里插入图片描述

@preconcurrency 修饰符可以应用在以下 4 种语境中:

  • functions
  • types
  • protocols
  • imports

那么接下来就让我们在这些语境中挑一些比较典型的使用情况和大家一起聊聊,以便充分了解 @preconcurrency 是如何帮助我们在启用严格并发检查时规避一些“细枝末节”的,即使暂时我们还不能更新所有的依赖项。

2. 导入中的 @preconcurrency

在我们导入第三方模块时,有时编译器会“贴心”的做出如下提示:

import MyModule

在这里插入图片描述

这个“错误”告诉我们:我们正在导入一个似乎还没有完全遵守现代并发规则的模块。由于这可能不是小伙伴们能够掌控的模块,于是乎 Xcode 提供了“消除”来自该模块严格并发警告和错误的能力。

在这里插入图片描述

我们可以通过在导入语句中添加 @preconcurrency 修饰符来达成此目的:

@preconcurrency import MyModule

通过这样一番操作,Xcode 将明了与来自 MyModule 类型相关的任何警告都应该被“抑制”。

如果 MyModule 不是我们自己的模块(没有源代码),那么消除该警告是非常有意义的,因为无论如何我们都无法修复它们。

值得注意的是:这样做不会“抑制”与 MyModule 中可发送(Sendable)或最新现代并发代码相关的警告。

因此,如果我们在用 @preconcurrency 标记的模块上看到与并发相关的警告时,大家一定希望随后能够在适当的时候修复这些警告,因为此时我们有点像“掩耳盗铃”的撸码者。

3. 类型修饰中的 @preconcurrency

另一种可能的情况是,我们正在处理一个采用 Swift 新并发模式的模块,并且已经修复了警告。

如果是这样的话,我们可能需要在一些声明中添加 @preconcurrency 修饰符,以确保依赖于我们模块的代码不会失去兼容性(“被打断”)。

这意味着采用 Swift 新并发检查会导致我们的模块 ABI 接口发生变化,如果旧代码不遵循 Swift 新并发范式,那么它们可能无法使用你无与伦比的模块。

如果小伙伴们正处于这种情况,我们可能已经转换了一些旧代码:

public class CatalogViewModel {public private(set) var books: [Book] = []public init() {}func loadBooks() {// 加载书籍}
}

到如下新代码:

@MainActor
public final class CatalogViewModel {public private(set) var books: [Book] = []public init() {}public func loadBooks() {// 加载书籍}
}

此时,倘若我们编写了一些使用 CatalogViewModel 类的并发代码,它们可能看起来有点像这样:

class TestClass {func run() {let obj = CatalogViewModel()obj.loadBooks()}
}

遗憾的是,上面的代码会被编译器“大爆粗口”:

Call to main actor-isolated initializer ‘init()’ in a synchronous nonisolated context.
Call to main actor-isolated instance method ‘loadBooks()’ in a synchronous nonisolated context.

这是因为将 @MainActor 添加到模块中的类中会使我们无法使用视图模型(View Model),除非我们自己将指令流分发到主线程上去。

为了与 CatalogViewModel 顺畅交互,我们需要更新项目以使用 @MainActor。不过,这通常会滚雪球般地导致越来越多的代码被修改,这会使我们模块中的更改严重的“物是人非”,讨厌的不要不要的。

这时,一种解决之道就是可以将 @preconcurrency 应用到我们的视图模型上,以允许尚未更新的代码与我们的视图模式达成“良好的共识”,就好像它从未被用 @MainActor 修饰过一样:

@preconcurrency @MainActor 
public final class CatalogViewModel {public private(set) var books: [Book] = []public init() {}public func loadBooks() {// 加载书籍}
}

注意:以上仅适用于未启用严格新并发检查的项目哦。


在为我们整个类应用 @preconcurrency 修饰后,编译器将该类的并发检查设置为最小(minimal)的等级,就好像 @MainActor 修饰不存在一样。如果使用严格的并发检查,编译器仍然会由于没有将 CatalogViewModel 与 @MainActor 一起使用而发出错误。

4. 一些使用提示

综上所示,我们使用 @preconcurrency 修饰符可以将旧模块导入到新代码中,并允许在旧项目中使用新代码。随着 Swift 6 的发布临近,这是一个逐步采用严格并发的好开头。

当我们导入尚未更新以实现严格并发的模块时,向导入语句中添加@preconcurrency 是非常有用滴。

另外,在注释为 @Sendable、@MainActor 或以其它方式更新的声明中添加@preconcurrency 修饰符,使其无法在非并发代码中使用,这对库作者来说也具有非同一般的意义。

现在,我们彻底搞懂了 @preconcurrency 的作用,大家的新并发功力愈发的炉火纯青了!小伙伴们还不赶紧给自已一个大大的赞吧!

总结

在本篇博文中,我们介绍了 Swift 语言中 @preconcurrency 修饰符的作用,以及它在一些应用语境中“雪中送炭”的具体示例。

感谢观赏,再会!😎

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

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

相关文章

在Spring Boot项目中使用Redisson实现延迟执行

提供一个完整的示例&#xff0c;演示如何在Spring Boot项目中使用Redisson实现延迟执行。 1. 添加Redisson依赖&#xff1a; 在你的pom.xml文件中添加Redisson的依赖&#xff1a; <dependency><groupId>org.redisson</groupId><artifactId>redisson-s…

模拟人为操作并获取数据

问题 假设需要获取一个微信公众号h5应用的某些数据&#xff0c;而这个应用存在如下一些反爬措施&#xff0c;从而决定了获取数据的方式。 每一个操作都有类似埋点行为&#xff0c;这样即可收集每个用户的操作轨迹。通过轨迹正常与否&#xff0c;很容易判断一个用户是否在恶意获…

【Spring Cloud Alibaba】开源组件Nacos及安装与配置

目录 什么是NacosNacos的关键特性服务发现和服务健康监测动态配置服务动态 DNS 服务服务及其元数据管理 Nacos的架构Nacos的用户Nacos的安装预备环境准备安装方式有两种&#xff1a;源码安装和下载编译好的安装包Nacos 支持三种部署模式&#xff0c;分别是单机、集群和多集群。…

性能飙升50%,react-virtualized-list如何优化大数据集滚动渲染

在处理大规模数据集渲染时&#xff0c;前端性能常常面临巨大的挑战。本文将探讨 react-virtualized-list 库如何通过虚拟化技术和 Intersection Observer API&#xff0c;实现前端渲染性能飙升 50% 的突破&#xff01;除此之外&#xff0c;我们一同探究下该库还支持哪些新的特性…

【Git篇 二】idea中使用git合并分支(拉取分支)

idea中使用git合并分支 前言idea使用git合并分支1) 将主分支&#xff08;master&#xff09;更新到自己的分支&#xff08;dev&#xff09;① checkout到自己分支② 目标分支&#xff08;dev&#xff09;更新到当前分支&#xff08;dev_KC240524&#xff09;③ 当前分支出现“绿…

【Python】 Python网络请求库大比拼:urllib、urllib2、urllib3与requests

基本原理 在Python中&#xff0c;进行网络请求是常见的任务之一&#xff0c;无论是下载网页内容、获取API数据还是进行文件上传。Python社区提供了多种库来帮助开发者完成这些任务。其中&#xff0c;urllib、urllib2、urllib3和requests是最为流行的几个。了解它们之间的区别对…

促进设备缺陷闭环管理,引入智能巡检系统正当时

经过近些年的应用与发展&#xff0c;智能巡检系统的功能与可操作性已经非常成熟&#xff0c;在巡检工作整合管理、与其他系统调用对接、促进设备缺陷闭环管理方面的优秀表现&#xff0c;使其在安全管理工作中的发挥了超预期的工具价值。 一、巡检工作整合管理 设备巡检管理、安…

QT 编译Lua 动态库,使用Lua脚本混合编程

一,编译Lua动态库 1,下载lua源码 地址:Lua: downloadhttps://www.lua.org/download.html 2,配置 解压lua源码压缩包,里面有个src文件夹,里面的代码就是lua的源码

Paper Survey——3DGS-SLAM

之前博客对多个3DGS SLAM的工作进行了复现及代码解读 学习笔记之——3DGS-SLAM系列代码解读_gs slam-CSDN博客文章浏览阅读1.9k次&#xff0c;点赞15次&#xff0c;收藏45次。最近对一系列基于3D Gaussian Splatting&#xff08;3DGS&#xff09;SLAM的工作的源码进行了测试与…

广东肇庆mes系统服务商 盈致科技

广东肇庆MES系统服务商盈致科技为企业提供专业的MES系统解决方案&#xff0c;帮助企业实现生产过程的数字化管理和优化。盈致科技的服务包括但不限于以下方面&#xff1a;MES系统定制开发&#xff1a;盈致科技可以根据企业的实际需求定制开发MES系统&#xff0c;满足企业特定的…

《猎杀:对决》是适合什么样的人玩 Mac电脑怎么玩《猎杀:对决》

《猎杀&#xff1a;对决》是一款集合了生存、竞技和恐怖元素的多人在线游戏&#xff0c;自推出以来受到了广大玩家的热爱。本文将详细探讨《猎杀&#xff1a;对决》适合什么样的人玩以及Mac电脑怎么玩《猎杀&#xff1a;对决》。本文将一一解析&#xff0c;帮助你了解这款游戏是…

maven中央仓库手动下载到本地仓库

1.maven中央仓库网址 maven中央仓库 2.搜索需要的jar包 3.点击坐标mybatis坐标进入 4.winR输入cmd打开命令窗口 mvn dependency:get -DremoteRepositoriesurl -DgroupIdgroupId -DartifactIdartifactId -Dversionversion5.maven本地仓库

判断JavaScript对象是否为空,最佳方法与性能对比

引言&#xff1a;在日常开发中&#xff0c;你是否经常需要判断一个对象是否为空&#xff1f;你知道有哪些高效的方法可以做到这一点吗&#xff1f;今天&#xff0c;我们不仅要探讨这些方法&#xff0c;还要通过性能对比找出最优解。快来看看&#xff0c;你平常用的方法是最佳选…

Python基础教程 第2版 PDF下载

Python基础教程 第2版 PDF下载 在数字时代的浪潮中&#xff0c;Python已成为众多程序员和数据分析师的首选编程语言。对于初学者来说&#xff0c;一本好的Python教程无疑是开启编程之门的金钥匙。本文将为您介绍如何下载《Python基础教程 第2版》的PDF版本&#xff0c;并从四个…

02_初识Nginx

文章目录 一、基础知识1.1 什么是代理服务器1.2 正向代理概述1.3 反向代理概述1.4 负载均衡1.5 动静分离 二、Nginx2.1 Nginx是什么2.2 Nginx的特点2.3 Nginx负载均衡策略2.4 Nginx的Master-Worker模式 参考链接 一、基础知识 1.1 什么是代理服务器 在最简单的场景下&#xf…

Linux安装gpu驱动

安装rpm包 进入官网 &#xff0c;选择机器的配置和环境。 下载完rpm之后&#xff0c;运行下面的命令。 i) sudo rpm -i nvidia-driver-local-repo-rhel8-550.54.15-1.0-1.x86_64.rpm ii) sudo dnf clean all iii) sudo dnf -y module install nvidia-driver:latest-dkms 安…

数据中心监控管理的实践方案

数据中心是信息存储和处理的核心&#xff0c;扮演着至关重要的角色2。然而&#xff0c;随着数据量的迅速增长&#xff0c;数据中心的监控和管理也变得愈发复杂和重要。保障数据中心的高效运作和安全性&#xff0c;依靠传统的管理方式远远不够。 实时监控数据中心的各项指标&am…

2024/5/30

In recent weeks, Target and Aldi have broadcast price cuts on thousands of items, while Walmart unveiled a new private label lineup of quality “chef-inspired food” mostly in the $5-and-under range. The shift comes as U.S. consumers have been signaling th…

煤矿塌陷位移监测站-全天候监测

TH-WY1煤矿塌陷位移监测站&#xff0c;作为矿山安全监测系统的重要组成部分&#xff0c;其设计、构建和功能均针对煤矿塌陷等地质灾害的实时监测与预警。 煤矿塌陷位移监测站&#xff0c;简称位移监测站&#xff0c;是一种利用先进传感器和仪器设备&#xff0c;对煤矿及周边区…

QML信号连接到c++的槽函数(五)

文章目录 前言一、QML Signal and Handler Event System二、QML信号连接到c++的槽函数代码实例1. 创建一个QML 工程2. 用C++ 实现一个QML Types3. 代码实例4. 运行结果总结参考资料前言 本文主要介绍,如何将QML 中的信号连接到C++ 中的槽函数 软硬件环境: 硬件:PC 软件:wi…