Swift 基础

@State @Binding

2019-09-26  本文已影响0人  幸运者_Lucky

@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 }
上一篇 下一篇

猜你喜欢

热点阅读