无法从 Class 更新 Published var
Posted
技术标签:
【中文标题】无法从 Class 更新 Published var【英文标题】:Unable to update Published var from Class 【发布时间】:2021-08-07 02:43:38 【问题描述】:我有一个已发布的 var prediction
:
class TrainingStatus: ObservableObject
@Published var isTrained: Bool = false
@Published var modelUrl: URL = URL(fileURLWithPath: "hello")
@Published var prediction:String = ""
我尝试在一个类中更新这个变量:
class ClassificationController: ObservableObject
...
func processObservations(for request: VNRequest, error: Error?)
DispatchQueue.main.async
if let results = request.results as? [VNClassificationObservation]
if results.isEmpty
print("nothing found")
else
print("got a result: \(results)!")
let top3 = results.prefix(3).map observation in
String(format: "%@ %.1f%%", observation.identifier, observation.confidence * 100)
self.prediction = top3.joined(separator: " ")
// attempt to set environment variable?
let trainingStatus = TrainingStatus()
trainingStatus.prediction = self.prediction
print("set prediction: \(trainingStatus.prediction)")
并在我的 UIView 中显示这个变量:
struct SidebarView: View
@EnvironmentObject var trainingStatus: TrainingStatus
var body: some View
VStack
NavigationView
Section
Text("Trained? " + String(trainingStatus.isTrained))
Text("Prediction: \(trainingStatus.prediction)")
.navigationTitle("Data")
.environmentObject(modelData)
.environmentObject(trainingStatus)
但是,尽管 prediction
的值似乎在 ClassificationController
中更新,但我的带有文本 \(trainingStatus.prediction)
的 UI 视图从未更新。
如何更新视图以获取最新发布的值?
【问题讨论】:
如您所见,您不能这样做:let trainingStatus = TrainingStatus() trainingStatus.prediction = self.prediction
。阅读更多关于如何使用 ObservableObject 以及如何传递它们的信息。您想要实现的是仅使用 1 个 TrainingStatus。
@workingdog 你能推荐一些关于如何正确设置可观察对象的资源吗?
【参考方案1】:
您可以有效地利用(几乎)单例。
您首先需要更改 ObservableObject 类并添加一个新常量:
class TrainingStatus: ObservableObject
@Published var isTrained: Bool = false
@Published var modelUrl: URL = URL(fileURLWithPath: "hello")
@Published var prediction:String = ""
public static let shared = TrainingStatus()
然后您可以通过声明以下内容在其他地方访问它:
var trainingStatus = TrainingStatus.shared
现在您可以随意修改它的值。这也将在 ObservableObject 类中更新它,因此在任何其他使用它的视图中更改它。
您的用例示例:
struct SidebarView: View
var trainingStatus = TrainingStatus.shared
var body: some View
VStack
NavigationView
Section
Text("Trained? " + String(trainingStatus.isTrained))
Text("Prediction: \(trainingStatus.prediction)") //This is now referencing your new shared variable of trainingStatus
.navigationTitle("Data")
.environmentObject(modelData)
.environmentObject(trainingStatus)
要修改常量的类:
class ClassificationController: ObservableObject
var trainingStatus = TrainingStatus.shared
...
func processObservations(for request: VNRequest, error: Error?)
DispatchQueue.main.async
if let results = request.results as? [VNClassificationObservation]
if results.isEmpty
print("nothing found")
else
print("got a result: \(results)!")
let top3 = results.prefix(3).map observation in
String(format: "%@ %.1f%%", observation.identifier, observation.confidence * 100)
self.prediction = top3.joined(separator: " ")
// attempt to set environment variable?
//let trainingStatus = TrainingStatus() --- no longer need this line
trainingStatus.prediction = self.prediction //this is now changing your singleton
print("set prediction: \(trainingStatus.prediction)")
【讨论】:
已编辑以在您提供的代码中添加示例以上是关于无法从 Class 更新 Published var的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI @Published 属性正在 DetailView 中更新
SwiftUI iOS 14 视图不使用 @EnvironmentObject 更新 @Published 数组
来自 @Published 属性的 SwiftUI 动画从视图外部更改
SwiftUI 将 @Published var 从一个 ObservableObject 映射到另一个