V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
FaiChou
V2EX  ›  Swift

Swift 关于 Binding 的疑问

  •  
  •   FaiChou ·
    FaiChou · 2022-09-15 16:42:30 +08:00 · 1276 次点击
    这是一个创建于 804 天前的主题,其中的信息可能已经有所发展或是发生改变。

    教程中使用 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 这种引用类型?

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

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


    补充个图 @kanel @MakHoCheung
    kanel
        11
    kanel  
       2022-09-15 18:51:09 +08:00
    因為 View Struct 就是這樣傳值的。
    MakHoCheung
        12
    MakHoCheung  
       2022-09-15 19:21:38 +08:00
    哦,传 @StateObject 的属性就要 @Binding
    agagega
        13
    agagega  
       2022-09-17 13:07:33 +08:00
    Palette 是 struct 吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5386 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 08:05 · PVG 16:05 · LAX 00:05 · JFK 03:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.