【发布时间】:2019-09-24 22:42:06
【问题描述】:
当您使用属性包装器时,您可以访问$varName 和_varName,但我并没有真正理解其中的区别。比如这里
import SwiftUI
struct ContentView: View {
@Binding var varName: String
var body: some View {
TextField("", text: $varName) //here you can also use `_varName`
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(varName: .constant("Hello world!"))
}
}
#endif
您可以同时使用$varName 和_varName。这两种解决方案似乎是等价的。两个变量都是Binding<String>。但如果我需要这样的东西:
import SwiftUI
struct ContentView: View {
@Binding var varName: String
init(varName: Binding<String>) {
self.$varName = varName //ERROR
}
var body: some View {
TextField("", text: $varName)
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(varName: .constant("Hello world!"))
}
}
#endif
我会得到一个错误:
无法分配给属性:“$varName”是不可变的
我必须使用_varName 来抑制错误:
struct ContentView: View {
@Binding var varName: String
init(varName: Binding<String>) {
self._varName = varName //this works fine
}
var body: some View {
TextField("", text: _varName)
}
}
他们仍然都是Binding<String>,那么为什么以前的解决方案不起作用呢?根据 Apple (https://developer.apple.com/videos/play/wwdc2019/415/) 的说法,编译器会将属性包装器变成两件事。这个:
@Binding var varName: String
变成:
//Compiler-synthesized code
var $varName = Binding<String> = Binding<String>()
public var varName: String {
get { $varName.wrappedValue }
set { $varName.wrappedValue = newValue }
}
$varName 应该是var,那为什么上面的错误呢?而且,最重要的是,_varName 是什么?它来自哪里?
【问题讨论】: