为什么这段代码不在 swiftui 中的结构中设置 @State 变量



我得到了下面的代码,看起来很简单。

import SwiftUI
struct Tester : View
{
@State var blah : String = "blah"
func setBlah(_ val : String) {
blah = val
}
var body: some View {
Text("text")
}
}
var test = Tester()
test.setBlah("blee")
print(test.blah)

我通常期望看到最后的打印语句显示&;blee",但它是&;blah"——变量不变。如果我通过绑定将blah传递到另一个视图,我就可以在那里更改blah的值。如果你有任何见解,包括rtfm,如果你能给我指出正确的手册,我将不胜感激。我已经看过了,还没有找到答案。

编辑:阅读@jnpdx的回答后,我有一个稍微不同的版本,但它仍然不起作用-我不担心这个特定的代码工作,但试图理解@jnpdx所指的魔力,就@State如何工作而言,以及为什么绑定传递到另一个视图能够修改原来的@State变量,而我无法在结构体本身。我猜SwiftUI的某些部分需要实例化,@State属性的通信,以便存储结构外的变量,如苹果文档所说。新版本如下:

import Foundation
import SwiftUI
struct Tester : View
{
@State var blah : String
func setBlah(_ val : String) {
$blah.wrappedValue = val
}
var body: some View {
Text("smoe text")
}
}
var test = Tester(blah: "blah")
test.setBlah("blee") // expect to see blee printed, but get nil instead
print(test.blah)

谢谢:)

SwiftUI中的@State不像结构体上的简单变异函数那样工作——它更像是一个单独的状态层,与视图层次结构一起存储。

让我们看看如果没有SwiftUI/@State:

struct Tester
{
var blah : String = "blah"
mutating func setBlah(_ val : String) {
blah = val
}
}
var test = Tester()
test.setBlah("blee") // prints correctly
print(test.blah)

注意上面,setBlah必须标记为mutating,因为它使struct发生突变。而在您的示例中,编译器不需要它,因为struct本身实际上并没有发生变化——@State属性包装器正在执行一些幕后的魔术。

查看State的文档:https://developer.apple.com/documentation/swiftui/state

特别是:

不初始化一个国家财产的一个视图在视图层次中实例化视图,因为这可以与SwiftUI提供的存储管理冲突。为了避免这种情况,始终将state声明为private,并将其放在需要访问该值的视图层次结构中的最高视图中。然后与任何需要访问的子视图共享状态,无论是直接用于只读访问,还是作为读写访问的绑定。

通过将@State标记为私有,您可以防止外部实体试图直接操纵它。然而,在您的示例中,您通过创建一个setter函数来避免private问题,即使它被包含在内。所以,实际上,setBlah也应该标记为private

最新更新