Ios 什么';SwiftUI中$varName和_varName的区别是什么
当您使用属性包装器时,您可以同时访问Ios 什么';SwiftUI中$varName和_varName的区别是什么,ios,swift,swiftui,Ios,Swift,Swiftui,当您使用属性包装器时,您可以同时访问$varName和\u varName,而我并不真正理解其中的区别。比如说这里, import SwiftUI struct ContentView: View { @Binding var varName: String var body: some View { TextField("", text: $varName) //here you can also use `_varName` } } #if DE
$varName
和\u 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
和\u varName
。这两种解决方案似乎是等价的。这两个变量都是绑定的。但如果我需要这样的东西:
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
它们仍然都是绑定的
,那么为什么前一个解决方案不起作用呢?根据Apple()的说法,编译器将把一个属性包装器转换成两件事。这:
@Binding var varName: String
变成:
//Compiler-synthesized code
var $varName = Binding<String> = Binding<String>()
public var varName: String {
get { $varName.wrappedValue }
set { $varName.wrappedValue = newValue }
}
//编译器合成代码
var$varName=Binding=Binding()
公共变量varName:String{
获取{$varName.wrappedValue}
设置{$varName.wrappedValue=newValue}
}
$varName
应该是var
,那么上面的错误是什么呢?最重要的是,那是什么?它来自哪里?合成的\u varName
属性是一个存储的、可设置的属性,它(在您的情况下)保存绑定的一个实例
varName
属性映射到包装的wrappedValue
属性。像这样:
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
由于wrappedValue
是用nonmutating set
声明的,因此合成的varName
属性始终是可设置的(即使self
是不可变的)
如果包装器具有projectedValue
属性,则合成的$varName
属性将映射到包装器的projectedValue
属性。像这样:
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
var projectedValue:Binding{get}
由于projectedValue
仅声明为get
,而不是get set
,因此永远不能将其分配给$varName
Binding
不需要提供projectedValue
属性,因为您可以使用\u varName
获取Binding
对象。Binding
声明projectedValue
属性的原因是使$
前缀在绑定
中的工作方式与在状态
、观测对象
和环境对象
中的工作方式相同,合成的\u varName
属性是一个存储的属性,可设置属性,该属性保存(在您的情况下)绑定的实例
varName
属性映射到包装的wrappedValue
属性。像这样:
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
由于wrappedValue
是用nonmutating set
声明的,因此合成的varName
属性始终是可设置的(即使self
是不可变的)
如果包装器具有projectedValue
属性,则合成的$varName
属性将映射到包装器的projectedValue
属性。像这样:
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
var projectedValue:Binding{get}
由于projectedValue
仅声明为get
,而不是get set
,因此永远不能将其分配给$varName
Binding
不需要提供projectedValue
属性,因为您可以使用\u varName
获取Binding
对象。Binding
声明projectedValue
属性的原因是使$
前缀在绑定
中的工作方式与在状态
、观察对象
和环境对象
中的工作方式相同。谢谢Rob,现在我明白了为什么我在这里制造混乱。一旦我有时间,我会添加更多的细节来更好地解释这个错误。谢谢Rob,现在我明白为什么我在这里制造混乱了。一旦我有时间,我会添加更多的细节来更好地解释这个错误。