以下代码在 Xcode 16 Beta 4 中运行良好,但在 beta 5 中无法编译:
@MainActor
class TimerSchudler {
init() {
}
}
class GameScene: SKScene {
let scheduler = TimerSchudler()
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我收到此错误:
属性“self.scheduler”未在 super.init 调用时初始化
然后我将
scheduler
初始化移动到 init
内:
class GameScene: SKScene {
let scheduler: TimerSchudler
override init() {
scheduler = TimerSchudler()
super.init()
}
}
这成为警告:
在同步非隔离上下文中调用主参与者隔离初始化程序“init()”;这是 Swift 6 语言模式下的错误
这意味着
TimerScheduler
的 init 函数现在位于主要角色上。
如果我将其更改为使用非主要演员的演员:
actor TimerSchudler {
init() {
}
}
class GameScene: SKScene {
let scheduler: TimerSchudler
override init() {
scheduler = TimerSchudler()
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这个编译得很好。这意味着非主要参与者的 init 仍然是非隔离的。
我的理解是所有参与者的 init 都应该是非隔离的。然而,看起来在 Beta 5 中,Apple 将 MainActor 的 init 设为 main actor 隔离。这是有问题的,因为
SKScene
的 init 不在主要演员上。因此,如果我像这样将 init 标记为主要参与者:
class GameScene: SKScene {
let scheduler: TimerSchudler
@MainActor
override init() {
scheduler = TimerSchudler()
super.init()
}
}
我会收到警告:
主参与者隔离初始化器“init()”与非隔离重写声明具有不同的参与者隔离;这是 Swift 6 语言模式下的错误
那么我该如何解决这个问题?
所有参与者的 init 都应该是非隔离的
正确。
Apple 将 MainActor 的 init 设为 main actor 隔离
您没有启动“MainActor”。您在与 MainActor 隔离的类(不是 Actor)上调用
init
。是的,那个 init
位于 MainActor 上,因为它继承了 @MainActor
属性。 (再次强调,属性。它不是一个 Actor。它是一个与 MainActor 隔离的类。)
那么我该如何解决这个问题?
您提供了方法并说“这编译得很好。”
如果需要,您还可以将
TimeSchudler.init
标记为非隔离:
@MainActor
class TimerSchudler {
nonisolated init() {
}
}