Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 什么';SwiftUI中$varName和_varName的区别是什么_Ios_Swift_Swiftui - Fatal编程技术网

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,现在我明白为什么我在这里制造混乱了。一旦我有时间,我会添加更多的细节来更好地解释这个错误。