我创建了这个复制我的应用程序架构的示例项目,其中在Manager
类中生成随机数,然后在SecondaryView
中显示。在这个视图中,需要根据这个randomNumber
进行计算,并显示(randomNumberTimesTen
)。这个例子当然是没有意义的,可以通过改变体系结构来修复。重要的是@State
和@EnvironmentObject
之间的关系,它们需要保持在原来的位置。
我如何确保SecondaryView
的主体只在randomNumberTimesTen
计算后更新一次,而不是两次?目前,它发生在randomNumber
生成后,这会导致我的应用程序中的问题,因为我需要randomNumberTimesTen
的值才能正确绘制body。
我认为有问题的部分可能是.onChange(of: manager.randomNumber)
,因为这可能只在主体更新时执行。有办法把这个转移到别的地方吗?multiplyByTen()
需要留在SecondaryView
中。
示例代码:
struct ContentView: View {
@StateObject var manager = Manager()
var body: some View {
VStack {
SecondaryView()
.environmentObject(manager)
Button("Random Number") {
manager.generateRandomNumber()
}
}
}
}
struct SecondaryView: View {
@State var randomNumberTimesTen: Int = 0
@EnvironmentObject var manager: Manager
var body: some View {
VStack {
Text("Random Number: (manager.randomNumber)")
Text("Random Number x10: (randomNumberTimesTen)")
}
.onChange(of: manager.randomNumber) { _ in
multiplyByTen()
}
}
func multiplyByTen() {
randomNumberTimesTen = manager.randomNumber * 10
}
}
public class Manager: ObservableObject {
@Published public var randomNumber: Int = 0
public func generateRandomNumber() {
self.randomNumber = Int.random(in: 0..<10)
}
}
你有两个"真相来源";改变了,所以有两个更新。所以做一个-manager.randomNumber
,因为它真的是这样,和其他的应该只是基于它。
这种情况可以通过使randomNumberTimesTen
可计算而不是状态来修复,如
struct SecondaryView: View {
@EnvironmentObject var manager: Manager
private var randomNumberTimesTen: Int {
self.manager.randomNumber * 10
}
var body: some View {
VStack {
Text("Random Number: (manager.randomNumber)")
Text("Random Number x10: (randomNumberTimesTen)")
}
}
}