Appearance
报错信息
error
🔴 Cannot use mutating getter on immutable value: 'self' is immutable
问题代码
首先根据报错的提示,不能在不可变值上使用可变getter: 'self'是不可变的。一开始我理解错了,因为报错的是使用的地方,我就以为是报错行的问题,但后来发现不管在哪用都会报错,所以其实是变量定义的有问题。
我所希望的result是一个计算属性,即是跟随isOn计算出来的,在查询过后我发现有着很大的问题,我原先错误的写法实际上还是一个存储属性,只不过是在初次赋值时计算了一次,后续不会再进行计算。
swift
lazy var result:Bool = isOn ? true : false
lazy var result:Bool = isOn ? true : false
计算属性的正确写法应该是这样:
swift
var result:Bool {
return isOn ? true : false
}
var result:Bool {
return isOn ? true : false
}
在修改后确实没有报错了。
mutating & immutable
虽然问题解决了,但是其实并没有理解报错的问题,我们再回到报错的信息当中,
报错可以分为两部分:
- Cannot use mutating getter on immutable value
- 'self' is immutable
第二部分很好理解,View是一个struct类型,也即值类型,而不是引用类型,当我们试图修改它的属性时实际上是创建了一个新的视图,而不是直接修改原始视图。 @State
关键字则是将值存储在一个单独的特殊位置,并且当该值发生更改时,SwiftUI会重新构建视图。所以当我们需要在View中通过变量控制View的变化,就需要设置为@State
或@Bind
。
由于直接使用var是不能驱动view的更新的,所以还有一个解决方案是把result写在body里,这样当isOn修改驱动view更新时会重新计算内部的变量,也可以实现计算效果。
而第一部分为什么lazy会引引发这个问题呢。。。 还有待解决
- [x]: lazy为什么会让变量变成mutating getter