SwiftUI中,作为环境对象的@StateObject是否应设计为单例?
注意:这是环境变量相关的特定场景,我并非认为所有@StateObject都应设计为单例(比如ViewModel),在我看来那样是错误的。
场景背景
在SwiftUI iOS应用中,我使用带有@Published属性的ObservableObject类实现设置功能:
final class Settings: ObservableObject { @Published var disableLockScreen = false // 示例属性 }
在@main标记的App结构体中,我通过@StateObject初始化该类,并将其注入到视图层级:
@main struct MyTestApp: App { @StateObject private var settings = Settings() var body: some Scene { MainView() .environmentObject(settings) } }
此时MyTestApp持有Settings实例,所有子视图都能通过@EnvironmentObject var settings: Settings便捷访问它。但我遇到了问题:我不仅需要在视图中访问Settings,还需要在非View结构体的ObservableObject类型ViewModel中访问它——比如在ViewModel中执行UIApplication.shared.isIdleTimerDisabled = settings.disableLockScreen这类与视图无直接关联的代码。
如果采用依赖注入的方式,在ViewModel初始化时传入Settings实例,会产生大量冗余代码,可读性也会大幅下降。
尝试的解决方案
我参考了相关方案,考虑将Settings改为单例,在MyTestApp中只需把Settings()替换为Settings.shared,依然用@StateObject持有并注入环境:
@main struct MyTestApp: App { @StateObject private var settings = Settings.shared var body: some Scene { MainView() .environmentObject(settings) } }
这样ViewModel只需通过Settings.shared就能访问其属性,无需依赖注入,实现起来简洁流畅。但我不确定这种方法是否合理,是否存在潜在问题?所有需要在环境中共享且被非View类型访问的@StateObject都应该设计为单例吗?
内容的提问来源于stack exchange,提问作者Jonathan

