我正在创建一个 Mac 应用程序。当多次启动时,所有窗口都应访问相同应用程序状态(
theAppState
),但每个窗口应显示自己的数据(类型为MyClass
)。
如下所示,当
MainWindow
创建 MyClass
对象时,它将绑定传递给 theAppState
。
MainWindow
有一个调用 obj.incBoth()
的按钮。结果,theAppState
增加(理应如此)。
身体以不同的方式显示
theAppState
:
self.appState
正确 显示,并且每次按下按钮都会增加。obj.appstate
未正确显示(始终显示原始值42)obj.appstate()
未正确显示(与 obj.appstate 相同)请帮助我理解这种奇怪的行为!
更新: 请注意,视图和
MyClass
对象 (obj) 都可以通过其本地绑定访问 theAppState
。在视图中, self.appState
返回 Correct 值,并且对象在 incBoth()
中打印出 Correct值。我觉得奇怪的是,视图无法通过
obj.appstate2()
间接访问 AppState 。您的评论表明不应在 StateObject
中使用绑定。这可能是正确的,但它确实解释了奇怪的行为。import SwiftUI
class MyClass : ObservableObject {
@Published var x = 0
@Binding var appstate : Int
init(appstate : Binding<Int> ){
self._appstate = appstate
}
func appstate2() -> Int {
return self.appstate
}
func incBoth() {
x+=1
appstate += 1
print("x=\(x) appstate=\(appstate)")
}
}
struct MainView : View {
@Binding var appState : Int
@StateObject var obj : MyClass
init(appstate: Binding<Int>){
self._appState = appstate
self._obj = StateObject(wrappedValue: MyClass(appstate: appstate))
}
var body: some View {
Text("appState = \(appState), obj.appstate = \(obj.appstate), obj.appstate2 = \(obj.appstate2()) obj.x = \(obj.x)")
Button("Inc") {
obj.incBoth()
}
}
}
@main
struct ProblemApp : App {
@State private var theAppState = 42
var body: some Scene {
WindowGroup {
MainView(appstate: $theAppState)
}
}
}
@State
可以只是一个结构,然后你可以将逻辑放入函数中,例如
struct TheAppState {
var x = 42
mutating func inc() {
x += 1
}
}
struct ProblemApp : App {
@State private var theAppState = TheAppState()
在 SwiftUI 中,状态被设计为去中心化的,因此您需要小心,仅将相关变量放在结构中,而不是全局变量中。否则
body
将不会像平常那样有效地被调用。
在 SwiftUI 中,通常尽量避免自定义类,因为这会导致一致性问题,而 Swift 使用结构的目的就是为了消除这种问题。