@Environment 与 @EnvironmentObject

Ham*_*dar 7 swiftui

SwiftUI 中的@Environment 和@EnvironmentObject 有什么区别?

从我从文档中发现的内容来看,@Environment 似乎旨在用于像 ColorScheme 这样的全局依赖项。但我找不到它们之间的任何确切区别。例如,它们可以互换使用吗?

Kar*_*raj 13

这是我为自己准备的笔记。可能有用,

@环境对象

  • 它的相似之处 @ObservedObject
  • 模型应确认 ObservableObject 协议
  • 我们需要标记此模型中的属性@Published以通知更改以查看哪些主动使用该对象
  • 模型对象肯定应该是类
  • 不需要默认值,因为它可以从环境中读取默认值。如果对象在环境中不可用,应用程序将崩溃
  • 另一个主要区别是,假设我们有 5 个视图(V1…V5),如果我们想将一个对象直接从 V1 传递到 V5,我们可以使用@EnvironmentObject而不是@ObservedObject。设置要在 V1 中传递的数据并在 V5(或任何需要的地方)中检索它。代码会简单很多。
  • 它将在同一时间环境中仅包含一种类型的实例。
  • 它纯粹基于观点。如果父视图设置环境对象,则其所有子视图都可以使用它。如果另一个父视图设置了另一个 env 对象,他们的子视图可以让我们使用它。例如:如果您在 SceneDelegate 的 ContentView 中设置环境对象,则其所有子视图都可以使用它。

@环境

  • 我们可以使用它来获取系统相关的值,例如应用程序是在明暗模式下运行、核心数据的托管对象上下文、大小类等...
  • 我们需要提供正确的键来访问它的值,因为它针对多个键持有相同的数据类型。

谢谢!?


LuL*_*aGa 5

@Enviroment 使您可以访问属性值,例如用户设置(例如配色方案、布局方向等)或视图的属性,例如 EditMode 或 PresentationMode。@EnviromentObject 由您定义,可用于所有视图,对其进行的更改会驱动您的视图更新。


ata*_*asa 5

它们@Environment都是@EnvironmentObject属性包装器,同时@Environment保留带有预定义键的值,@EnvironmentObject不仅保留预定义键,还保留任意值。例如,如果您需要保留有关用户对象的信息,其中包括姓名、年龄、性别等,您需要使用@EnvironmentObject,而如果您想保留设备是处于深色模式还是浅色模式、系统本地语言、日历首选项,请编辑模式非常适合使用@Environment

@Environment(\.locale) var locale: Locale

@EnvironmentObject var user: User // is an object where you keep user-related information
Run Code Online (Sandbox Code Playgroud)


and*_*ewz 5

@Environment是一个键/值对,而@EnvironmentObject是一个由其类型标识的值。两者都是变量存储属性包装器。


Sha*_*afi 5

我想在其他人的答案中添加一些内容。

@Environment类型但是@EnvironmentObject引用类型。

您只能在 中使用单个对象实例@EnvironmentObject。如果添加另一个对象实例,它将替换前一个实例。

但是,作为@Environment键值对,只需确保键不同即可。

您只需要使用@EnvironmentObject var object: Object使对象从环境中检索实例,并通过以下方式注入实例.environmentObject(Object())

另一方面,有许多预定义的@Environment系统管理环境值。您也可以创建自定义的。它需要是struct类型并符合EnvironmentKey.

这是一个例子

struct SunlightKey: EnvironmentKey {
    static var defaultValue: Double = 1.09
}
Run Code Online (Sandbox Code Playgroud)

然后将其添加到 中EnvironmentValues作为它的扩展。

这是一个基本的例子

extension EnvironmentValues {
    
    var sunlight: Double {
        get { self[SunlightKey.self] }
        set { self[SunlightKey.self] = newValue }
    }
    
}
Run Code Online (Sandbox Code Playgroud)

然后,@Environment(\.sunlight) var sunlight在视图文件中使用它并通过以下方式注入.environment(\.sunlight, 4.05)

希望这可以帮助

  • 添加到环境中的东西不需要是值类型。如果需要,您可以添加课程。举例来说,您有一个类,您不想导致视图重新加载。就像也许您有一些类可以在您点击视图时记录分析。你可以通过环境传递它。 (2认同)