Swift中对协议和Actor的隔离
我正在使用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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。