提问人:Trufa 提问时间:11/8/2023 更新时间:11/8/2023 访问量:87
ObservableObject 和存储 NSWindow 对象的@State有什么区别
What is the difference between ObservableObject and @State to store a NSWindow object
问:
我正在动态/编程地创建这样的窗口:
func createWelcomeWindow() {
let w = WelcomeScreenView().frame(width: 400, height: 600)
let hostingController = NSHostingController(rootView: w)
appState.welcomeWindow = NSWindow(contentViewController: hostingController)
appState.welcomeWindow?.title = "Welcome to Last Warning"
appState.welcomeWindow?.collectionBehavior = [.moveToActiveSpace, .fullScreenAuxiliary]
appState.welcomeWindow?.makeKeyAndOrderFront(nil)
}
appState 是这样创建的:
class AppState: ObservableObject {
@Published var warningWindow: NSWindow?
@Published var welcomeWindow: NSWindow?
}
@main
struct LastWarningApp: App {
@ObservedObject var appState = AppState()
我对 swift 中的状态管理感到困惑。
我试过了,主要是出于好奇,换了
@main
struct LastWarningApp: App {
@State var welcomeWindow: NSWindow?
然后做:
welcomeWindow = NSWindow(contentViewController: hostingController)
welcomeWindow?.title = "Welcome to Last Warning"
welcomeWindow?.collectionBehavior = [.moveToActiveSpace, .fullScreenAuxiliary]
welcomeWindow?.makeKeyAndOrderFront(nil)
但这并没有创建窗口,我想知道为什么会这样,据我所知,问 chatGPT,@State似乎用于管理视图的状态,不适合这个,我已经浏览了尽可能多的 github 存储库,试图查看最佳实践,但我找不到明确的方法来解决这个问题。
我注意到了一件事,但我不确定,那就是当我调试它时,似乎没有设置欢迎窗口。
那么,这是一个合理的方法吗?为什么@State在这种特殊情况下不起作用?
这也让我感到困惑,我可以做:
@State var appState = AppState()
行为保持不变。
答:
@State
作为事实来源,并在“值”发生变化时重新绘制。body
没有任何问题
@State var appState = AppState()
您只需要知道,更改引用类型的属性不会触发重绘,因为该值不会更改。<<<<< 非常重要
ObservableObject
需要一系列的东西才能工作。
@Published
在值更改时发出,>合成“Object”属性包装器>发出以使 .ObservableObject
View
现在的“间隙”,不是 or 的引用类型,这些可以存储,但不会重绘,因为没有机制。ObservableObject
Obervable
@State
View
您可能需要在 SwiftUI 中存储这些内容,因为 SwiftUI 是一种值类型,可以随时由 SwiftUI 重新创建。如果您不使用它,您最终将获得多个实例。View
与“Object”属性包装器存在差异。 用于初始化,用于传递。StateObject
ObservedObject
@ObservedObject var appState = AppState()
不正确.....
你应该使用
@StateObject var appState = AppState()
这背后的主要区别在于可以访问 SwiftUI 拥有的秘密存储。
在 iOS 13 中,初始化的“正确”方式是 ,但我们无法观察到它,直到我们可以使用的下一个视图。 是在 iOS 14 中引入的。ObservableObject
State
ObservedObject
StateObject
现在这是 SwiftUI 属性包装器的基础知识,但我认为您最大的问题是您混合了 SwiftUI 和 AppKit,SwiftUI 有一种非常不同的窗口管理方式。
https://developer.apple.com/videos/play/wwdc2022/10061/
https://developer.apple.com/documentation/swiftui/bringing_multiple_windows_to_your_swiftui_app
在 .App
@main
struct BookClub: App {
@StateObject private var store = ReadingListStore()
var body: some Scene {
WindowGroup {
ReadingListViewer(store: store)
}
Window("Activity", id: "activity") {
ReadingActivity(store: store)
}
}
}
你向他们展示类似的东西
struct OpenWindowButton: View {
@Environment(\.openWindow) private var openWindow
var body: some View {
Button("Open Activity Window") {
openWindow(id: "activity")
}
}
}
评论
NSWindow
createWelcomeWindow
WindowGroup
Window