当前位置: 首页 > 知识库问答 >
问题:

swift 中的 全局变量提示 并发不安全,该怎么处理?

庄弘业
2024-04-15

代码这样写

private let logger = Logger(subsystem: subsystem, category: "menu")

提示:

Let 'logger' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6

共有2个答案

戴瑞
2024-04-15

使用actor包装一下

晏修诚
2024-04-15

在 Swift 6 中,Swift 引入了新的并发模型,要求所有的全局变量和闭包捕获的变量都必须是 Sendable 的,以确保它们可以在多个线程或异步任务之间安全地传递。这有助于避免数据竞争和其他并发问题。

如果 Swift 提示你的全局变量 logger 不是并发安全的,那么你有几种方法可以解决这个问题:

  1. 将变量标记为 Sendable
    如果 Logger 类或其初始化方法可以被安全地发送(即它不包含任何不安全的引用或状态),那么你可以将 Logger 类标记为 Sendable。这可以通过在类定义前添加 @Sendable 注解来实现。
@Sendableclass Logger {    // ...}
  1. 使用全局 actor 隔离变量
    如果 Logger 类或其初始化方法不能被标记为 Sendable,或者你希望确保 logger 实例的访问是线程安全的,你可以使用全局 actor 来隔离 logger。全局 actor 确保在任何时候只有一个任务可以访问其隔离的代码块。
actor MyGlobalActor {    private let logger = Logger(subsystem: subsystem, category: "menu")        // 提供访问 logger 的方法}

然后,你可以通过 MyGlobalActor.async { /* 访问 logger */ } 的方式异步地访问 logger

  1. 重新设计代码
    如果上述方法都不适用,你可能需要重新设计你的代码,以避免使用全局变量,或者确保所有的变量都是 Sendable 的。这可能涉及到将状态移入结构体或类,使用依赖注入来传递依赖项,或者重新考虑你的并发策略。

在处理并发问题时,重要的是要确保你理解数据的流动和共享方式,并采取相应的措施来避免数据竞争和不一致。在 Swift 6 中,通过显式地处理并发,你可以编写更加健壮和可维护的代码。

 类似资料:
  • 问题内容: 该文件说: Swift编译器会自动将C和Objective-C源文件中定义的全局常量作为Swift全局常量导入。 但这并没有说相反的话。我需要定义一个全局swift常数,并且能够像全局c常数一样客观地看到它。如快速定义: 并在物镜c端使用它,例如 我该怎么办?我已经导入了迅速自动生成的标题,例如: 在Xcode中,如果我使用它,它将带我到swift代码中的正确位置,但是在编译时,我得到

  • 问题内容: 我想制作一个可以在整个应用程序中访问的自定义对象的全局数组(AppDelegate,ViewController类,TableViewController类等)。我已经研究了一种解决方法,但没有找到答案。我曾尝试将数组设置为公共范围,但是收到了编译器警告,提示当我尝试在其他文件中访问该数组时,出现错误提示 我将如何使该数组可被应用程序中的所有文件全局访问,我将在哪里实例化该数组? 问题

  • 卸载全局后,使用npx create-react-app my-app初始化也不行

  • 本文向大家介绍Lua中的全局变量、非全局变量总结,包括了Lua中的全局变量、非全局变量总结的使用技巧和注意事项,需要的朋友参考一下 前言 Lua将其所有的全局变量保存在一个常规的table中,这个table称为“环境”。这种组织结构的优点在于,其一,不需要再为全局变量创造一种新的数据结构,因此简化了Lua的内部实现;另一个优点是,可以像其他table一样操作这个table。为了便于实施这种操作,L

  • 如果你要多于一个函数共用一个简单的变量,简单的处理方法就是把这个变量在所有函数中定义为global全局变量。在命令行做同样的事情,如果你要工作空间访问上述变量。这个全局变量的定义必须出现在变量被应用于一个函数之前。虽然不是要求,但全局变量也最好以大写字母开头,这样可以同其他变量区别出来。举个例子,做一个以falling.m命名的M-文件。 function h = falling(t) globa

  • ThinkCMF封装了前台模板开发时常用的一些变量,这些变量是全局的,你在前台模板任何时候都能直接调用: {$site_name} /站点名称 {$site_host} /站点域名 {$site_root} /安装目录 {$site_icp} /