Swift 关于 Binding 的疑问

2022-09-15 16:42:30 +08:00
 FaiChou

教程中使用 environment 来注入了一个 class 的实例 @StateObject var a = SomeClass(), 在某页面中(SwiftUI) 将这个 a 传递给一个子页面, 需要在子页面中使用 @Binding, 传递时候需要使用 $a 来传递它的 projectedValue.

我的疑惑: class 不是 reference 类型吗? 为什么还要这样传递? 比如:

class Foo {
    var a: String
    init(a: String) {
        self.a = a
    }
}
var foo = Foo(a: "aaa")
print(foo.a)
var bar = foo
bar.a = "bbb"
print(foo.a) // bbb
func baz(f: Foo) {
    f.a = "xxx"
}
baz(f: bar)
print(foo.a) // xxx

可能是因为 @StateObject 作用让它发生了变化? 为什么不直接使用 class 这种引用类型?

1298 次点击
所在节点    Swift
13 条回复
foxwe10
2022-09-15 16:55:05 +08:00
`Binding` 是一个 `struct`, 你可以看下 SwiftUI 关于 `Binding` 的声明 interface
kanel
2022-09-15 17:03:31 +08:00
要用 @Binding 的原因是因為值的改變會導致系統重新刷新使用該變數的 UI 元件
kanel
2022-09-15 17:10:35 +08:00
@Binding 是要告訴系統,當該變數的值改變的時候,重新刷新使用該變數的 UI 元件
FaiChou
2022-09-15 17:13:38 +08:00
@kanel 谢谢, 那这么说我就懂了, `@Published` `@State` `@Binding` 这三种方式可以让数据变化时候 UI 自动刷新, 如果直接传递引用, 不会触发刷新, 这么理解对吧.
eric1202
2022-09-15 17:22:15 +08:00
响应式 接受值更改的通知
MakHoCheung
2022-09-15 17:29:05 +08:00
@StateObject 不需要 @Binding 配合啊,子页面再用 @StateObject 修饰 a 就可以了
kanel
2022-09-15 17:36:22 +08:00
@FaiChou 抱歉,我記錯了。

`@State` 才是當該變數的值改變的時候,重新刷新使用該變數的 UI 元件。
`@Binding`是當類的屬性使用了`@Binding` Annotation 的時候,調用類的屬性加上$,可以把屬裝為 Binding<?>的類型以與被調用類的屬性進行綁定,此值是按地址傳值的。
kanel
2022-09-15 17:51:04 +08:00
`@StateObject`是指該 model 對象只會被創建一次,不會在以後新的 UI 生命週期中重新創建 model 對象。
kanel
2022-09-15 17:52:47 +08:00
三者雖然都是用在 class 裡的變數上,但是前兩者跟後者不是在一個概念上。
FaiChou
2022-09-15 18:01:41 +08:00


补充个图 @kanel @MakHoCheung
kanel
2022-09-15 18:51:09 +08:00
因為 View Struct 就是這樣傳值的。
MakHoCheung
2022-09-15 19:21:38 +08:00
哦,传 @StateObject 的属性就要 @Binding
agagega
2022-09-17 13:07:33 +08:00
Palette 是 struct 吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/880307

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX