@EnvironmentObject 和 @ObservedObject 有什么区别? [英] What is the difference between @EnvironmentObject and @ObservedObject?

查看:33
本文介绍了@EnvironmentObject 和 @ObservedObject 有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读有关 SwiftUI 中的属性包装器的信息,我发现它们做得很好,但我真正不明白的一件事是 @EnvironmentObject 之间的区别@ObservedObject.

I have been reading about the property wrappers in SwiftUI and I see that they do a great job, but one thing which I really don't get is the difference between @EnvironmentObject and @ObservedObject.

从我目前学到的,我看到 @EnvironmentObject 用于当我们的应用程序的各个地方都需要一个对象但我们不需要将它传递给所有他们.例如,如果我们有层次结构 A ->B->C->D 并且对象是在 A 处创建的,它保存在环境中,以便我们可以将它直接从 A 传递给 D,如果 D 需要的话.

From what I learned so far, I see that @EnvironmentObject is used when we have an object that is needed in various places in our app but we don't need to pass it through all of them. For example if we have hierarchy A -> B -> C -> D and the object is created at A, it is saved in the environment so that we can pass it directly from A to D, if D needs it.

如果我们使用在 A 创建并需要传递给 D 的 @ObservedObject,那么我们也需要通过 B 和 C.

If we use @ObservedObject which is created at A and needs to be passed to D, then we need to go through B and C as well.

但我仍然不知道如何决定使用哪个.以下是我制作的 2 个示例项目:

But I still don't know how to decide which one to use. Here are 2 example projects which I made:

struct ContentView2: View {
 
   var order = Order2()

   var body: some View {
      VStack {
           EditView2()
           DisplayView2()
       }
       .environmentObject(order)
   }
}
struct EditView2: View {
   @EnvironmentObject var user: Order2
 
   var body: some View {
       HStack{
       TextField("Fruit", text: $user.item)
       }
   }
}
struct DisplayView2: View {
   @EnvironmentObject var user: Order2
   var body: some View {
       VStack{
       Text(user.item)
       }
   }
}
class Order2: ObservableObject {
       @Published var item = "Orange"
   }

struct ContentView: View {

    var order = Order()
    
    var body: some View {
       VStack {
            EditView(order: order)
            DisplayView(order: order)
        }
    }
}
struct EditView: View {
    @ObservedObject var order: Order
    var body: some View {
        HStack{
        TextField("Fruit", text: $order.item)
        }
    }
}
struct DisplayView: View {
      @ObservedObject var order: Order
      var body: some View {
        VStack{
        Text(order.item)
        }
    }
}
class Order: ObservableObject {
    @Published var item = "Apple"
}

两个代码都对视图进行相同的更新.同样,两个 ContentViews 都传递一个 Order 对象.区别在于Environment传递.environmentObject(order),Observed直接传递EditView(order: order).对我来说,两者都做同样的工作,只是他们的声明不同,因此我希望得到一些解释或更好的例子.

Both codes do the same update of the view. Also both ContentViews, pass an Order object. The difference is that Environment passes .environmentObject(order) and Observed passes it directly EditView(order: order). For me, both do same job, only their declaration is different, therefore I would appreciate some explanation or a better example.

推荐答案

正如您所注意到的,@ObservedObject 需要在视图之间传递.当您没有太多视图时,使用简单的视图层次结构可能会更好.

As you've noticed an @ObservedObject needs to be passed from view to view. It may be better for a simple view hierarchy when you don't have too many views.

假设您有以下层次结构:

Let's assume you have the following hierarchy:

ViewA -> ViewB -> ViewC -> ViewD

现在,如果您希望 ViewA 中的 @ObservedObject 位于 ViewB 中,则直接在 中传递它没有问题初始化.

Now if you want your @ObservedObject from the ViewA to be in the ViewB there's no problem with passing it directly in init.

但是如果您也希望在 ViewD 中使用它呢?如果在 ViewBViewC 中不需要它怎么办?

But what if you want it in the ViewD as well? And what if you don't need it in the ViewB and ViewC?

使用 @ObservedObject,您需要手动将其从 ViewA 传递到 ViewB,然后再传递到 ViewC,然后到 ViewD.并且您需要在每个子视图中声明它.

With an @ObservedObject you'd need to manually pass it from the ViewA to the ViewB and then to the ViewC, and then to the ViewD. And you'd need to declare it in every child view.

使用 @EnvironmentObject 很容易 - 只需将其传递给顶级视图:

With an @EnvironmentObject it's easy - just pass it to the top-level view:

ViewA().environmentObject(someObservableObject)

然后你只在使用它的视图中声明它 - 这可能会使你的代码更具可读性.

Then you only declare it in the view that uses it - this may make your code more readable.

注意

环境中的每个对象(视图层次结构)都可以访问注入的@EnvironmentObject.如果您不想要这个(隐私很重要),您可能需要将其作为 @ObservedObject 传递.

Every object in the environment (view hierarchy) can access the injected @EnvironmentObject. If you don't want this (privacy is important) you may need to pass it as an @ObservedObject instead.

这篇关于@EnvironmentObject 和 @ObservedObject 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆