编辑代码

我们应该使用 @StateObject 在某处创建可观察对象,
并且在传递该对象的所有后续地方应该使用 @ObservedObject。
需要注意,请不要使用 @ObservedObject 创建对象的实例,
如果这是想要做的,请改用 @StateObject。

每当在属性包装器中看到“State”时,
例如 @State@StateObject@GestureState,
可以理解为:“当前视图拥有这些数据”。

@ObservedObject 使用的任何类型都应该符合 ObservableObject 协议
使用 @Published 属性包装器通知视图重要数据发生了更改

SwiftUI 的 @EnvironmentObject 属性包装器,
可以创建依赖于共享数据的视图,
通常跨整个 SwiftUI 应用程序。

@EnvironmentObject@ObservedObject 有很多共同点:
两者都必须引用一个符合 ObservableObject 的类,
两者都可以在多个视图之间共享,
并且都将在发生重大变化时更新任何正在观察的视图。

实际上,想象一下如果您有视图 A,并且视图 A 有一些视图 E 想要的数据,
使用@ObservedObject 视图 A 需要将对象交给视图 B,
视图 B 将把它交给视图 C,然后是视图 D,最后是视图 E,
所有中间视图都需要发送对象,即使它们实际上并没有需要它。

使用 @EnvironmentObject 时,视图 A 可以创建一个对象并将其放入环境中;
然后,其中的任何视图都可以随时通过请求访问该环境对象,而不必显式传递它,
这样会使我们的代码更简单。

以上是中文文档,无示例
以下是英文文档,有示例

1@State只能用于简单类型,such as Ints, Strings, and Bools.
不适用于结构体和类等复杂类型。
2@StateObject,存在于视图生命周期中,跳出再回就会重置。
3@ObservedObject is used to keep track of an object that has already been created。
You have already instantiated the Observable Object using @StateObject in the parent view,
 and now you want a child view to have access to the data. But, you don’t want to recreate the object again. 
以上等待验证。

Use @EnvironmentObject to consume an ObservableObject that has already been created
 in a parent view and then attached via the view’s environmentObject() view modifier.
 没理解

Image.Scale.large
和Image(systemName: "globe")
                .imageScale(.large)的关系?
区别:Image.Scale.large:这是一个枚举值,表示图像的缩放比例。.imageScale(.large) 是对图像的一个修改器,用来将图像的大小设置为大号。
联系:Image(systemName: "globe").imageScale(.large) 实际上使用了 Image.Scale.large 作为参数,以指示如何缩放指定的图像。

Change the foreground color to another semantic color such as “primary” or a standard color like “teal”.

结构体不先赋值是为了能复用?

看英文时习惯性逐语块翻译,突然想,这语块我知道它表达的动作(大致意思)吗?
若已知道,那我还用翻译成中文吗?如果不翻译就这样推下去会怎样?

Although symbols are images, they support many traits you associate with text.

This sample shows examples of using State variables to indicate data dependencies,
 and sharing data with other views using the Binding property wrapper.

"Source of Truth" 是指在一个应用中,为了确保数据的一致性和准确性,
设置的一个权威性的数据来源或数据存储位置。

The most common way to define a source of truth that binds to other views in your app
 is to declare a state variable using the State property wrapper.

知识不都是线性的,有时像网一样,学会其他点后才能理解当前点。
另外,潜意识的概念,当时不明白的,几天后再看,已经明了。
所以,遇见困难不要泄气,放一放缓一缓,或者咬牙挺过去。

当你使用 @Binding 属性时,记住它是一个动态的值包装器,需要用 $ 来解包以获得其值或某些方法来访问。
CircleView 视图使用 @Binding 来接受父视图 ContentView 中的圆数据。
比如在父视图ContentView中:CircleView(circle: $circle, activeCircleId: $activeCirID)
在CircleView视图中: @Binding var circle: CircleData  @Binding var activeCircleId: UUID?

结论:在复杂的状态管理中,特别是当你有多个视图需要访问和观察同一个数据集时,使用 @StateObject@Published 是更好的选择。
如果你只是想在一个简单的视图中跟踪某个局部状态,那么使用 @State 是合适的。
@Published:用于类中的属性(通常是在 ObservableObject 中)。当一个 @Published 属性的值发生变化时,所有观察这个对象的视图都会自动更新。
适合于状态较为复杂的场景。例如,如果有多个视图需要共享和观察同一个状态,而状态的更新来自隐藏在视图之外的逻辑层(如 GameManager),那么使用 @Published 就非常合适。
@StateObject:用于表示一个遵循 ObservableObject 协议的类的实例,并且这个实例的生命周期由 SwiftUI 管理。它适用于在视图内创建并维护一个对象的状态。
这种方式能确保在每次视图更新时,ObservableObject 的实例保持存在,从而确保数据保持一致性。

结论:在Swift中,如果你想在struct中使用可观察的属性(即,当它的值发生变化时,可以通知视图更新),
通常最常见的方式是使用@State@Binding,而不是@Published。 这是因为@Published是专门为ObservableObject类设计的。
@State:适合较为简单的状态管理,主要是局部状态或不需要在多个视图之间共享的状态。
这是为SwiftUI视图设计的,用于管理本地状态。 它只在视图中有效,不能在其他类型中使用。
@Binding用途:它是用来连接一个视图中的状态与其父视图提供的状态。通过 @Binding,子视图可以读写来自父视图的状态,同时保持数据的双向绑定。
适用场景:当你需要在子视图中修改父视图的状态而又希望保持同步时,可以使用 @Binding。它主要用于建立子视图与父视图之间的状态共享。

@StateObject@ObservedObject区别:
适用场景: 当你在视图中创建并管理一个 ObservableObject 实例时,应该使用 @StateObject。通常是在视图初次加载时创建一个新对象,并在视图消失时不再关注该对象。
适用场景: 当你在一个视图中接收一个已经创建的 ObservableObject 实例(通常是由父视图创建的),并且需要在视图中观察其变化时,应该使用 @ObservedObject。
示例:
class ViewModel: ObservableObject {
    @Published var count = 0
}

struct ContentView: View {
    @StateObject private var viewModel = ViewModel()

    var body: some View {
        ChildView(viewModel: viewModel)
    }
}

struct ChildView: View {
    @ObservedObject var viewModel: ViewModel

    var body: some View {
        Text("Count: \(viewModel.count)")
    }
}