如何修复“需要全局 actor 'MainActor' 的表达式不能出现在属性 '_audioPlaybackManager' 的默认值表达式中”?

Swi*_*ast 22 swift swiftui

我创建了一个名为“AudioPlaybackManager”的类,它是应用程序启动时作为 StateObject 的 MainActor 类。我收到这个警告。我该如何解决?

@main
struct TestApp: App {
    @StateObject var audioPlaybackManager = AudioPlaybackManager() //This line is giving warning to me
    
    @StateObject var dataController = DataController()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
   .environmentObject(audioPlaybackManager)
                
        }
    }
}

@MainActor class AudioPlaybackManager: ObservableObject {
    ...
}
Run Code Online (Sandbox Code Playgroud)

the*_*max 26

编辑 2:这个问题已在 Swift 5.7 中得到解决(发行说明):

\n
\n

Xcode 13.3 版本中为 Swift 5.6 引入的有关非隔离默认值表达式的诊断不再可用。SE-0327 中提议的规则\xe2\x80\x99 不够精确,无法避免标记涉及 @StateObject 属性和 @MainActor 的 SwiftUI 代码中无害但常见的模式。(88971160)

\n
\n

我假设 Swift 6.0 中将引入更精确的规则。

\n
\n

编辑:正如迈克尔·朗在评论中提到的,我已经猜到,这可能不会\xe2\x80\x99t成为最终的解决方案。相反,问题可能会在编译器中得到解决,并且现有语法将在没有警告的情况下工作。

\n

根据您对警告的严格程度,您也可能暂时接受警告而不更改代码。或者您应用下面的修复并TODO: clean up syntax立即用 进行注释:)

\n
\n

建议的解决方案是不向属性提供默认值,而是在初始值设定项中设置其值。

\n

请参阅Xcode 发行说明中的​​ Swift 5.6 -> 已解决的问题。

\n

对于您的代码,修复如下:

\n
@main\nstruct Pro_Music_2App: App {\n    @StateObject var audioPlaybackManager: AudioPlaybackManager\n    \n    @StateObject var dataController = DataController()\n\n    init() {\n        self._audioPlaybackManager = StateObject(wrappedValue: AudioPlaybackManager())\n    }    \n\n    var body: some Scene {\n        WindowGroup {\n            ContentView()\n                .environmentObject(audioPlaybackManager.manager)\n                .environmentObject(audioPlaybackManager)\n                .environmentObject(audioPlaybackManager.manager.playlistManager)\n                .environmentObject(audioPlaybackManager.musicPlayerViewManager)\n                .environmentObject(audioPlaybackManager.scrubberViewModel)\n                .environment(\\.managedObjectContext, dataController.container.viewContext)\n                \n        }\n    }\n}\n\n@MainActor class AudioPlaybackManager: ObservableObject {\n    ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

根本问题是初始化器不是async。因此,您不能在不同的演员之间跳转。由于编译器为默认值合成了一个初始值设定项,因此这也会影响默认值。也就是说,如果您的DataController注释使用了与 不同的全局角色@MainActor,那么初始化程序必须在@MainActor和您在 上使用的任何角色之间跳转DataController。然而,这是不可能的,因为init不可能async

\n

我想在编译器中实现对存储属性默认值的单参与者检查会很困难,因此他们只是决定在这种情况下不允许参与者保护默认值。因此,我们必须自己编写初始化程序。

\n

参考:https: //github.com/apple/swift-evolution/blob/main/proposals/0327-actor-initializers.md#stored-property-isolation

\n