我试图要求提供
thing
,而不是使用 defaultValue = Thing()
作为默认值提供。 如果我使用 Thing? 将环境设置为可选,那么我必须在每个视图中展开它。 如果没有这种方法,当我需要传递特定实例时,我的初始化程序似乎总是被调用两次。
我正在尝试使用下面的代码,但它一运行就会抛出致命的“未提供东西”。 不过,我在 thingApp 中提供环境,所以我很困惑为什么会发生这种情况。 即使不使用
@Environment(\.thing) var thing
也会发生。
import SwiftUI
@main
struct thingApp: App {
var thing = Thing()
var body: some Scene {
WindowGroup {
ContentView().environment(\.thing, thing)
}
}
}
struct ContentView: View {
@Environment(\.thing) var thing
var body: some View {
Text("count: \(self.thing.count)")
}
}
@MainActor
@Observable class Thing {
var count: Int = 3
func inc() {
self.count = self.count + 1
}
}
private struct ThingKey: EnvironmentKey {
static var defaultValue: Thing {
fatalError("Thing not provided")
}
}
extension EnvironmentValues {
var thing: Thing {
get { self[ThingKey.self] }
set { self[ThingKey.self] = newValue }
}
}
崩溃的原因是,在您的情况下,SwiftUI 在通过关键路径写入环境值时首先读取环境值。
但即使事实并非如此: 根据定义,自定义 EnvironmentKey 实现必须实现默认值,因为如果未在视图上显式设置或覆盖该值,则应该能够检索它们。
作为旁注,使用 Entry 宏可以有更短的语法:
extension EnvironmentValues {
@Entry var thing: Thing = /* your default value */
}
但是,您可以使用不同的方法来获得您想要的行为:
import SwiftUI
@main
struct thingApp: App {
var thing = Thing()
var body: some Scene {
WindowGroup {
ContentView().environment(thing)
}
}
}
struct ContentView: View {
@Environment(Thing.self) var thing
var body: some View {
Text("count: \(self.thing.count)")
}
}
@MainActor
@Observable class Thing {
var count: Int = 3
func inc() {
self.count = self.count + 1
}
}
如果环境中没有该类型的对象,此方法将抛出异常。