Swift中对协议和Actor的隔离

移动开发 2026-07-09

我正在使用Swift 6和 Xcode 26为 macOS开发一款交易所监控应用。为了在交易所中维持来自不同交易对象的信息,我使用以下协议:

protocol DerivativeSymbol {
    associatedtype Ticker: DerivativeTicker

    var baseCoin: String {get }
    var quoteCoin: String {get }

    var ticker: Ticker? {get set}
}
protocol DerivativeTicker {
    var ask1Price: Double { get set }
    var bid1Price: Double { get set }
    var ask1Size: Double { get set }
    var bid1Size: Double { get set }
    var lastPrice: Double { get set }
    var indexPrice: Double { get set }
}

以及下列actor:

actor DerivativeSymbolActor<Symbol: DerivativeSymbol> {

    var data: [String: Symbol] = [:]
    var indexPrice: [String: Double] = [:]
// ...
    func updateOptionTicker(symbol: String, ticker: Symbol.Ticker) {
        data[symbol]?.ticker = ticker
    }
// ...
    func getAllPairsByBaseAsset(base: String) -> [Symbol] {
        return data.values.filter({$0.baseCoin == base})
    }
// ...
}

在updateOptionTicker函数中,我收到了如下警告:

被MainActor隔离的属性 'ticker' 不能在非隔离的Actor实例上被修改。

而在getAllPairsByBaseAsset中,我又收到了一个警告:

被MainActor隔离的属性 'baseCoin' 不能从非隔离的上下文中引用。

我猜这些警告是因为协议默认对MainActor进行了隔离。是否有办法在我的DerivativeSymbolActor 中将它们标记为被隔离?

解决方案

在Swift 6.2中,MainActor的隔离对整个项目来说是 默认的

所以基本上这些协议实际上看起来是这样的

@MainActor protocol DerivativeTicker {

@MainActor protocol DerivativeSymbol {

你可以通过修改 "Default Actor Isolation" 构建设置来改变这一点,但如果你选择非隔离,你在构建一个遵循结构化并发的安全应用时需要考虑很多事项。

另外,如果你选择 "default main actor" 并且打算引入额外的actor,例如 actor 或自定义 globalActor,你必须通过指定 nonisolated 来表示其他对象可以离开 MainActor

nonisolated protocol DerivativeTicker {

nonisolated protocol DerivativeSymbol {

但你也应该让它们 Sendable

Sendable: 一种线程安全的类型,其值可以在任意并发上下文之间共享,而不会带来数据竞争的风险。

这将使这些现在可能不安全/未隔离的对象变得安全

nonisolated protocol DerivativeTicker: Sendable {

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

相关文章