这是 EnvironmentKey
的定义:
public protocol EnvironmentKey {
associatedtype Value
static var defaultValue: Self.Value { get }
}
我对
defaultValue
属性的用途感到困惑。也许我对@Environment
的预期用途感到困惑。让我解释...根据我的测试,我知道正在访问
defaultValue
。例如,如果您将defaultValue
定义为 setter/getter :protocol MyInjector: EnvironmentKey {
static var defaultValue: Foo {
print("get default value!")
return Foo()
}
}
您会发现SwiftUI经常调用此属性(因此,在实践中,我将
defaultValue
定义为static let
)。当您在打印语句上添加断点并向下移动堆栈时,它会停在以下箭头上:
extension EnvironmentValues {
var myInjector: Foo {
get { self[MyInjector.self] } <-----------------
set { self[MyInjector.self] = newValue }
}
}
在堆栈的最下方是组件的
init
中的行,我可以在其中访问以下变量:@Environment(\.myInjector) var foo: Foo
也就是说,似乎只要重新渲染带有
defaultValue
变量的SwiftUI View ,就可以访问@Environment
。我认为
@Environment
的内部实现需要在确定实际值之前设置此默认值,以避免将变量声明设为可选。最后,我还尝试将
@Environment
添加到ObservableObject
中,希望它可以访问与SwiftUI View 树相同的“环境”。class Bar: ObservableObject {
@Environmenet(\.myInjector var foo: Foo
}
不幸的是,情况并非如此,
Bar
接收到的实例与我通过View.environment(\.myInjector, Foo())
注入(inject)的实例不同。我还发现,顺便说一句,我可以通过共享变量模式使用
@Environment
注入(inject)全局单例:protocol MyInjector: EnvironmentKey {
static let defaultValue = Foo()
}
SwiftUI View 和任何其他类都可以使用相同的实例,但是我不确定这在任何情况下如何有用。
那么
defaultValue
的目的是什么?我怀疑这是简单的事情,以便内部实现可以在确定真实值之前为该变量分配一个任意值,还是发生了其他情况? 最佳答案
IMO有两种原因在这种模式下使用defaultValue
(我认为这是故意的):
1)指定对应的值类型
2)使环境值始终有效(使用@Environment
)
在SwiftUI: Set Status Bar Color For a Specific View帖子中,您可以找到此defaultValue
功能用法的示例,以通过环境轻松地连接应用程序的不同部分。
关于swift - 为什么EnvironmentKey具有defaultValue属性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59586767/