@ObservedObject
我在使用和时观察到一种奇怪的模式@Published
。
我将其注入SwiftUI
视图内部,但视图似乎在对象实际更改之前刷新。
因此,@ObservedObject
当我检查它的属性时,我的值不正确@Published
。
如果我添加一个didSet
,objectWillChange.send()
它就会按预期工作。
以下是我正在使用的代码:
class AuthManager: ObservableObject {
@Published public private(set) var user: User {
willSet { print("Will set") }
didSet { print("Did set") }
}
}
struct AuthView: View {
@ObservedObject var authManager: AuthManager
var body: some View {
let _ = Self._printChanges()
print("AuthManager user = \(authManager.user)")
return (
Text("AuthManager Test")
)
}
}
当我在 AuthManager 中更新我的用户对象时,我按以下顺序获取日志:
Will set
AuthView: @self, @identity, _authManager
AuthManager user = xxx // <-- old version
Did set
如果我移除并在中@Published
触发,则行为将按预期工作。objectWillChange.send()
didSet
ObservableObject
我希望视图自动刷新时显示新版本。我是否遗漏了什么,或者我对and有什么不理解@Published
?
谢谢
objectWillChange
发布者总是ObservableObject
在处理程序中发出一个新事件willSet
:查看官方文档。
因此,您在这方面观察到的行为是正常的。
如果更改属性值
Published
,则会规划新的布局流程,但不会直接执行。这样可以先收集所有更改,然后在下一个布局流程中一起应用。请看以下示例,对您的代码稍作修改,您将看到输出符合预期:
按下按钮后的输出将是:
您在代码中没有向我们展示的是如何改变
user
的值AuthManager
。有很多因素都可能导致您所描述的问题。例如,如果您没有从主线程更改值。请注意我是如何将
ContentViewModel
示例中的 绑定到 的MainActor
。您的日志输出也不寻常。更改
user
属性不应导致视图的结构标识发生变化,您实际应该看到的唯一日志输出是:@self
并且@identity
不应包含在日志输出中。因此,此输出表明您在父视图、另一个周围视图
AuthView
或更改Published
属性的方式中遇到了问题。