如何在预览中构建带注释的 swiftui 类 mainactor

Dar*_*key 6 concurrency swiftui

所以 - 我有一个名为设置的类,我在所有地方都使用它 - 并且特别希望其他视图在内容更改时做出反应。我用 @MainActor 注释了它 - 当运行应用程序时,一切正常。

但是,在预览中我只是尝试创建一个实例:

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {        
        Group {
            ContentView( settings: Settings())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

突然间,虽然主程序编译并运行良好,但预览却无法正常运行。

在同步非隔离上下文中调用主参与者隔离初始化程序“init()”。

我可以使用如下代码来解决这个问题:

struct ContentView_Previews: PreviewProvider {
    
    var settings : Settings
    
    static func get_settings() -> Settings
    {
        var the_array : [Settings] =  []
        DispatchQueue.main.asyncAndWait( execute: DispatchWorkItem {
            the_array.append( Settings())
        })
        return the_array[0]
    }
    
    init()
    {
        self.settings = ContentView_Previews.get_settings()
    }
    
    static var previews: some View {        
        Group {
            ContentView( settings: Settings())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这显然是荒谬的。我确信有更好的方法 - 但不知道它是什么 - 我怎样才能在一两行中完成此操作,而不必创建辅助函数?

顺便说一句 - 此代码每次都会使预览提供程序崩溃:



struct ContentView_Previews: PreviewProvider {
        
    static func get_settings() -> Settings
    {
        var the_array : [Settings] =  []
        DispatchQueue.main.asyncAndWait( execute: DispatchWorkItem {
            the_array.append( Settings())
        })
        return the_array[0]
    }
  
    static var previews: some View {        
        Group {
            ContentView( settings: get_settings())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 9

对于那些使用新的 Xcode 15 beta 的用户。目前,使用@MainActor新的#Preview.

在解决此问题之前,建议的解决方法的示例如下:

#Preview {
    MainActor.assumeIsolated {
        AppTabView(viewModel: MockAppTabViewModel())
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 8

我能够通过使用 @MainActor 注释预览结构来解决此问题

@MainActor
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {        
        Group {
            ContentView( settings: Settings())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)