@State @Binding

作者: 幸运者_Lucky | 来源:发表于2019-09-26 15:04 被阅读0次

    @StateRN 的一样, 就是 UI 和 数据的同步, 当值改变的时候 UI 同时改变

    struct ContentView: View {
        @State var text = "1"
        var body: some View {
            VStack {
                Text(text)
                    .newStyle().padding()
                Button(action: add, label: { Text("Add") })
            }
        }
        
        func add() {
            text = "2"
        }
    }
    

    @Binding 现在 Swift 里面大多是值类型, @Binding 就是为了同步值类型, 不同页面传递的值类型属性, 被 @Binding 标记后, 前后使用同一个对象. 不会发生 Copy on Write.

    struct ContentView: View {
        @State var text = "1"
        var body: some View {
            VStack {
                Text(text)
                CustomText(text: $text)
                Button(action: add, label: { Text("Add") })
            }
        }
        
        func add() {
            withUnsafePointer(to: &text) {
                print($0)
            }
            text = text + text
        }
    }
    
    struct CustomText: View {
        @Binding var text: String
        var body: some View {
            VStack {
                Text(text)
                Button(action: add, label: { Text("Button") })
            }
        }
        
        func add() {
            withUnsafePointer(to: &text) {
                print($0)
            }
            text = text + text
        }
    }
    

    通过上面代码运行可以看到, Text(text) CustomText(text: $text) 显示的内容是相同的, 无论改变哪个 var text, 然后打印了一下两个 text 的地址, 发现他们的地址相同, 如下代码, 所以说 @Binding 前后两个值对象是同一个

    struct ContentView: View {
        @State var int = 0
        @State var string = "0"
        var body: some View {
            VStack {
                Text("\(int)")
                Text(string)
                CustomText(string: $string, int: $int)
                Button(action: add, label: { Text("Add") })
            }
        }
        
        func add() {
            withUnsafePointer(to: &int) {
                print("int: \($0)")
            }
            
            withUnsafePointer(to: &string) {
                print("string: \($0)")
            }
            string = string + "0"
            int += 1
        }
    }
    
    struct CustomText: View {
        @Binding var string: String
        @Binding var int: Int
        var body: some View {
            VStack {
                Text("\(int)")
                Text(string)
                Button(action: add, label: { Text("Button") })
            }
        }
        
        func add() {
            withUnsafePointer(to: &int) {
                print("custom int: \($0)")
            }
            
            withUnsafePointer(to: &string) {
                print("custom string: \($0)")
            }
            string = string + "0"
            int += 1
        }
    }
    
    custom int: 0x00007ffee4c1e410
    custom string: 0x00007ffee4c1e3f8
    int: 0x00007ffee4c1e410
    string: 0x00007ffee4c1e3f8
    

    struct 本身是无法通过 self, 来修改自己的属性的, self 本身是不可修改的, 即为 let, 但 @Binding var 修饰的属性可以在 struct 中, 通过self 修改, 因为调用的 set 方法标记为 nonmutating
    , 具体细节请参考 @propertyWrapper

    @BindingwrappedValue 具体细节参考如下:

    /// The value referenced by the binding. Assignments to the value
        /// will be immediately visible on reading (assuming the binding
        /// represents a mutable location), but the view changes they cause
        /// may be processed asynchronously to the assignment.
        public var wrappedValue: Value { get nonmutating set }
    

    相关文章

      网友评论

        本文标题:@State @Binding

        本文链接:https://www.haomeiwen.com/subject/ctuquctx.html