这篇由苹果公司关于SwiftUI的教程使用美元符号来绑定数据,我在寻找更多关于SwiftUI中数据绑定的信息时遇到了困难。
Toggle(isOn: $showFavoritesOnly) {
你可以使用$前缀来访问状态变量的绑定或者它的属性。
这是一种类似于inout类型参数的东西吗?它使用&符号进行传递。
这篇由苹果公司关于SwiftUI的教程使用美元符号来绑定数据,我在寻找更多关于SwiftUI中数据绑定的信息时遇到了困难。
Toggle(isOn: $showFavoritesOnly) {
在WWDC 2019视频415中,这个问题解释得非常清楚。您只是看到了一种广泛的语言特性中的一个特殊情况,即属性包装器。
属性包装器(例如@State
)实际上是引用具有相同名称(例如State)的类型实例(通常为结构体或枚举类型)的一种方式。后者提供了将此实例属性转换为计算属性的说明,其getter和setter是其自身的某个计算属性(其wrappedValue
)。它还通常保存支持该计算属性的私有存储。
因此,在声明之后,
@State var showFavoritesOnly = true
showFavoritesOnly
被转换为计算属性,其getter和setter由State结构提供。当您将showFavoritesOnly
设置为true时,它会通过State结构的setter进行路由,并最终进入State实例的存储属性。
所有这些都意味着在某处与您的showFavoritesOnly
相关联的存在一个State实例。确实如此,但它被隐藏了起来。如果您想看到该State实例的名称,则为_showFavoritesOnly
。
但是,当您说$showFavoritesOnly
时,您并没有得到一个State结构;您得到一个Binding结构。为什么?因为属性包装器具有指定从$
名称返回值的机制。对于State而言,它指定该值应为其自己的binding
属性,该属性是Binding(请参阅文档:https://developer.apple.com/documentation/swiftui/state)。
出乎巧合的是,Toggle的isOn
初始化程序采用了绑定(再次参见文档:https://developer.apple.com/documentation/swiftui/toggle/3232112-init)。即使您想,也无法将Toggle的isOn
设置为showFavoritesOnly
!相反,您将其设置为State实例提供的Binding<Bool>
,以便Toggle与State对象自动进行双向通信。SwiftUI框架强制执行其自己的正确使用;Toggle仅可以存在于某个绑定的关系中,该绑定作为其开/关状态的基础真相源。由于它是绑定而不是普通的布尔值,因此通信可以在两个方向上工作:当用户在Toggle中点击开关时,值的更改会通过绑定传递“向上”至State变量。
$
与属性包装器(以前称为“property delegates”)一起使用。
它不是运算符,而是一个前缀(感谢 @matt!)。
有关属性包装器的更多信息,请参阅此Swift Evolution 文档。
例如,在@State var aState = false
中,State
是一个属性包装器。
这意味着如果我们写:
aState
,我们正在访问一个Bool
值$aState
,我们正在访问一个Binding<Bool>
值不同的属性包装器将生成不同的值,称为“projected values”。
$aState
才是真正的绑定。 - matt@State
属性包装器的 projectedValue
具有类型 Binding
。 - DanSkeel@State
和 @Binding
变量中的 _aState
,这是什么意思?据我所知,下划线与美元符号的作用相同。 - vrwim