这是 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/

10-10 21:11