Swift 中 @preconcurrency 修饰符使用浅谈

news2024/12/23 10:17:15

在这里插入图片描述

概述

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.coloradmin.cn/o/1717688.html

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

相关文章

视频删除怎么恢复?这2个方法或许能帮到你

随着科技的发展,手机视频的拍摄和存储技术也不断提高,在我们的生活中也扮演着越来越重要的角色,或是作为新媒体工作者的工作内容,或是成为我们分享生活的途径,视频占据的分量越来越重。然而,由于各种原因&a…

10- Redis 键值对数据库是怎么实现的?

在开始将数据结构之前,先给介绍下 Redis 是怎样实现键值对(key-value)数据库的。 Redis 的键值对中的 key 就是字符串对象,而 value 可以是字符串对象,也可以是集合数据类型的对象,比如 List 对象&#xf…

JAVA应用服务器如何快速定位CPU问题

如果服务器上部署了多个Java站点服务和Java微服务,并且突然接收到CPU异常告警,我们需要逐步确定是哪个服务进程造成了CPU过载,接着是哪个线程,并最终定位到是哪段代码导致了这个问题 简要步骤如下: 步骤一、找到最耗C…

用Idea 解决Git冲突

https://intellijidea.com.cn/help/idea/resolving-conflicts.html https://www.jetbrains.com/help/idea/resolve-conflicts.html idea 官方文档 当您在团队中工作时,您可能会遇到这样的情况:有人对您当前正在处理的文件进行更改。如果这些更改没有重叠(也就是说…

深入分析 Android Service (一)

文章目录 深入分析 Android Service (一)1. Android Service 设计说明1.1. Service 的类型1.2. Service 的生命周期1.3. 创建和启动 Service1.4. 绑定 Service1.5. ServiceConnection1.6. 前台 Service1.7. IntentService示例:创建和使用 IntentService 2. Service …

视频汇聚EasyCVR平台GA/T 1400视图库应用:助力社会治安防控效能提升

在信息化、智能化的时代浪潮下,公安视频图像信息应用系统的发展与应用显得尤为重要。GA/T 1400标准,全称为《公安视频图像信息应用系统》,作为公安行业的一项重要标准,其视图库的应用在提升公安工作效能、加强社会治安防控等方面发…

通过强化学习彻底改变大型数据集特征选择

文章目录 一、说明二、强化学习:特征选择的马尔可夫决策问题三、用于使用强化学习进行特征选择的 python 库3.1. 数据预处理3.2. 安装和导入FSRLearning库 四、结论和参考文献 一、说明 了解强化学习如何改变机器学习模型的特征选择。通过实际示例和专用的 Python 库…

TrueNAS开启SSH登录ROOT

简介: 从 SCALE Bluefin 22.12.0 开始,为了加强安全性并遵守联邦信息处理标准 (FIPS),root帐户登录已被弃用。所有 TrueNAS 用户都应创建具有所有必需权限的本地管理员帐户,并开始使用它来访问 TrueNAS。当根用户密码被禁用时,只有管理用户帐户才能登录 TrueNAS Web 界面。…

[Linux]重定向

一、struct file内核对象 struct file是在内核中创建,专门用来管理被打开文件的结构体。struct file中包含了打开文件的所有属性,文件的操作方法集以及文件缓冲区(无论读写,我们都需要先将数据加载到文件缓冲区中。)等…

#centos7搭建php8+nginx环境#

场景:为了实现上传的pdf文件转成png图片,需要搭建一个php8nginx的运行环境,最后安装imagic扩展 安装顺序 php-> linux-> imagemagick -> ghostscript -> imagick 一:安装phpnginx环境 1、安装remi扩展源 remi源是Remi repository是包含最新…

消安一体化解决方案

前言 随着信息技术的飞速发展,物联网技术正以前所未有的速度渗透至生活的各个角落,其中智能家居作为物联网技术应用的重要场景之一,不仅提升了居住的便捷性,更是对家庭安全提出了新的挑战和要求。在这样的背景下,将消防…

161.二叉树:在每个树中找最大值(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

易联众智能自动办理平台,AI赋能让数字政务服务“触手可及”

“城乡居民参保怎么办”“要去XX省工作了,帮我办理异地就医备案”……通过口语化的文字、语音提问,易联众智能自动办理平台的AI助理都可以准确理解对话,并依据政策文件给出详细回答,人机对话像聊天一样轻松。 近日,宁德市民王先生高兴地说:“过去办理医保业务不懂流程,容易走弯…

第22讲:文件操作

文章目录 第22讲:文件操作1. 为什么使用文件2. 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 3. 二进制文件和文本文件?4. 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭 5. 文件的顺序读写5.1 顺序读写函数介…

文刻创作ai工具

文刻创作AI工具是一种利用人工智能技术来辅助创作文本的工具。 领取激活方式:https://qvfbz6lhqnd.feishu.cn/wiki/HsY4wmoffiNp4FkB2AbcpL4tn6d 它能够生成、修改、编辑和优化各种类型的文本内容,包括文章、故事、诗歌、广告文案等。 通过分析大量的文…

比较好的Python课程

最近在学习夜曲编程的Python进阶课程——办公效率化;夜曲编程之前有推出一款学习Python的入门课程,在手机端和电脑端都可以学习的,如果没有时间在手机端学习都很好的。每节课程学习下来,可以收集到Python入门的知识卡片&#xff0…

全志H616 通过Cedrus和v4l2_request API实现硬件编解码加速(香橙派zero2)

编译安装或加载cedrus驱动模块,加载v4l2-mem2mem Sunxi-Cedrus 致力于为全志 SoC 提供硬件加速的视频解码和编码支持,并将其引入主线 Linux 内核。此外,还为典型的基于 GNU/Linux 的系统提供了与内核驱动程序接口的其他用户空间组件。 Sunx…

Java使用Hutool工具类轻松生成验证码

👩🏽‍💻个人主页:阿木木AEcru 🔥 系列专栏:《Docker容器化部署系列》 《Java每日面筋》 💹每一次技术突破,都是对自我能力的挑战和超越。 目录 一、效果展示1.1 扭曲干扰的验证码1.…

C++学习第十一天——vector的模拟实现

✨ 生于火焰,落俗不可避免,但浪漫至死不渝 🌏 📃个人主页:island1314 🔥个人专栏:C学习 🚀 欢迎关注:👍点赞 &…

白玉兰之争王一博vs王阳谁将摘得男主荣耀

白玉兰之争:王一博VS王阳,谁将摘得男主荣耀?在这个星光璀璨的夜晚,白玉兰奖的提名名单犹如一道耀眼的闪电,点燃了娱乐圈的硝烟。其中,王一博与王阳入围白玉兰男主角的消息更是引发了热议狂潮。两位实力派演…