错误:将 [StructType] 对 [ProtocolType] 的符合性跨入主Actor隔离的代码,在易于理解的并发模型中

移动开发 2026-07-09

我已经开启了approachable concurrency,默认以主Actor作为隔离。我有这段代码:

protocol RLActionState: CustomDebugStringConvertible {}
struct RLWaitActionState: RLActionState {}

我有一个警告:

对协议 'RLActionState' 的RLWaitActionState的一致性跨入了主Actor隔离的代码,可能导致数据竞争;在Swift 6语言模式下这是一个错误。

然后我发现这段代码可以工作:

struct RLWaitActionState: @MainActor RLActionState {}

而这段则不起作用:

@MainActor 
extension RLWaitActionState: RLActionState {}

我的问题是:

  1. 默认情况下,一切都应该在主Actor中,那么为什么还需要 @MainActor?
  2. @MainActor extension Foo: Protocol {}extension Foo: @MainActor Protocol{} 有何区别,为什么一个能工作、一个会失败。

我看过 为什么 @Model对 PersistentModel和 Hashable的符合会跨入Swift 6.2的 @MainActor隔离? ,但它们不是同一个用例。

Playground中的完整示例:

import UIKit

@MainActor
protocol RLActionImpl {}


@MainActor
struct RLWaitActionImpl: RLActionImpl, @MainActor CustomDebugStringConvertible {
  let duration: TimeInterval
  var debugDescription: String {
    "wait(\(duration))"
  }
}


@MainActor
protocol RLActionState: CustomDebugStringConvertible {
  associatedtype Impl: RLActionImpl
  var action: Impl { get }
  var key: String? { get }
}

@MainActor
extension RLActionState {
  var debugDescription: String {
    if let key {
      "\(key)->\(action)"
    } else {
      "\(action)"
    }
  }
}

@MainActor
struct RLWaitActionState: RLActionState {
  typealias Impl = RLWaitActionImpl
  let action: RLWaitActionImpl
  let key: String?
}

解决方案

这里的关键点在于 CustomDebugStringConvertible 是一个非隔离协议。因此,RLActionState 也是非隔离的。

“默认以主Actor”为准并不适用于 RLActionState,因为它继承自一个非隔离协议。但它确实适用于 RLWaitActionState——RLWaitActionState 的所有成员都是主Actor隔离的,这并不符合该协议对非隔离的要求。

这就是你仍然需要像下面这样进行隔离符合性来让它编译的原因:

struct RLWaitActionState: @MainActor RLActionState {}

另一方面,这个:@MainActor extension RLWaitActionState: RLActionState {} …完全是多余的。默认的“主Actor”设置本来就会把这个 @MainActor 属性应用到你所有的扩展上。这里的 @MainActor 只是让扩展中的所有成员都成为主Actor隔离。

这与 isolated conformance 的概念不同,后者允许你用全局Actor隔离的成员来满足本应非隔离的协议要求。作为代价,你就不能自由地使用这类类型的值。有关更多细节,请参阅链接中的SE提案。

也就是说,isolated conformances仍然算是一种有点问题的特性

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章