在SwiftUI中,@Published
是一个属性包装器,用于在ObservableObject中发布属性的变化,以便视图能够自动更新。如果你想要“转发”一个@Published
值,通常意味着你想要在一个视图模型中接收另一个视图模型的@Published
属性的变化,并将其转发到自己的一个属性中,以便可以在视图中使用。
ObservableObject: 是一个协议,它要求遵循者提供一个objectWillChange
发布者,当对象的属性即将发生变化时,这个发布者会被通知。
@Published: 是一个属性包装器,它自动为包装的属性创建一个Publisher,并在属性值变化时发出新值。
@Published
属性变化时,所有订阅了这个属性的视图都会自动刷新。@Published
,你可以避免手动调用更新视图的代码。@Published
可以用于任何遵循ObservableObject
协议的类的属性上。假设我们有两个视图模型ViewModelA
和ViewModelB
,我们想要在ViewModelB
中转发ViewModelA
的@Published
属性。
import SwiftUI
import Combine
class ViewModelA: ObservableObject {
@Published var valueA: String = ""
}
class ViewModelB: ObservableObject {
@Published var valueB: String = ""
private var cancellable: AnyCancellable?
init(viewModelA: ViewModelA) {
cancellable = viewModelA.$valueA
.receive(on: RunLoop.main)
.assign(to: &$valueB)
}
}
struct ContentView: View {
@StateObject private var viewModelA = ViewModelA()
@StateObject private var viewModelB = ViewModelB(viewModelA: ViewModelA())
var body: some View {
VStack {
TextField("Enter text", text: $viewModelA.valueA)
Text("Value from ViewModelA: \(viewModelA.valueA)")
Text("Forwarded value in ViewModelB: \(viewModelB.valueB)")
}
}
}
问题: 如果在ViewModelB
中转发的值没有更新,可能是因为ViewModelA
的实例在ViewModelB
初始化时没有被正确传递。
解决方法: 确保在创建ViewModelB
实例时传入了正确的ViewModelA
实例。在上面的示例中,我们在ContentView
中创建了两个视图模型的实例,并将viewModelA
传递给viewModelB
。
ViewModelA
的实例在ViewModelB
中是持久的,否则当ViewModelA
被释放时,ViewModelB
将无法接收到更新。AnyCancellable
来管理Combine的订阅,以避免内存泄漏。通过这种方式,你可以有效地在SwiftUI应用中转发@Published
值,实现状态的共享和视图的自动更新。
领取专属 10元无门槛券
手把手带您无忧上云