[英]How does $ work in SwiftUI and why can I cast a @StateObject to an @ObservedObject
[英]Does @StateObject work for static properties, such as SwiftUI Previews?
我不确定这是否是错误,但据我所知,@ static
@StateObject
一起使用时似乎表现得像@ObservedObject
。
预期行为:制作了一个实例,它在预览的渲染之间共享,因此每次按下按钮都会增加相同的 integer。
实际行为:似乎在每次渲染预览时都会创建一个新实例,导致计数器永久清零。NSLog 语句证实了这种情况。
这是一个说明问题的示例:
import SwiftUI
struct ContentView: View {
let title: String
@ObservedObject var state: DummyState
var body: some View {
Text("\(title): \(state.counter)").padding()
}
}
struct ContentView_Previews: PreviewProvider {
// Doesn't work as expected. Seems to act just like `@ObservedObject`,
// i.e. a new instance is made on every render.
@StateObject static var buggyState = DummyState()
// Works as expected, only 1 instance is created.
static let tmp = DummyState()
@ObservedObject static var workingState = tmp // @StateObject also works
static var previews: some View {
VStack {
ContentView(title: "Broken counter", state: buggyState) // Counter is always 0
ContentView(title: "Working counter", state: workingState)
Button {
buggyState.counter += 1;
workingState.counter += 1;
let _ = NSLog("""
DummyState
initCount: \(DummyState.initCount),
latestID: \(ObjectIdentifier(buggyState))
""")
}
label: { Text("++") }
.padding()
}.frame(width: 400, height: 200)
}
}
// This is some state I want to define in my Preview, and pass into my View to render.
class DummyState: ObservableObject {
/// Tracks how many instances of `DummyState` were ever made
static var initCount = 0
@Published var counter = 0
init() { Self.initCount += 1 }
}
作为一种解决方法,我发现我可以使用一个常规的static
变量来保存我的一个DummyState()
引用,然后创建第二个@ObservedObject
static 变量来为其添加别名,然后它会按预期工作。
那么,这是一个错误,还是我遗漏了什么?
这些属性包装器仅适用于视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.