选择建议
1.@ObservedObject:适用于对象实例只需在几个相邻视图间共享,且你想明确控制对象传递的情况。
2.@EnvironmentObject:适合在整个视图层次结构中共享对象,能避免在每个子视图中手动传递对象。
3.单例模式:当你需要在应用的不同部分全局共享一个对象实例,且不依赖 SwiftUI 特定机制时可使用。
1. 使用 @ObservedObject
@ObservedObject 适合在多个视图间共享对象实例,你需手动将对象实例传递给子视图。
示例代码
import SwiftUI
import Combine
// 定义一个遵循 ObservableObject 协议的类
class SharedViewModel: ObservableObject {
@Published var sharedData: String = "初始数据"
func updateData() {
sharedData = "更新后的数据"
}
}
// 父视图
struct ParentView: View {
@StateObject private var viewModel = SharedViewModel()
var body: some View {
VStack {
Text("父视图: \(viewModel.sharedData)")
Button("更新数据") {
viewModel.updateData()
}
ChildView(viewModel: viewModel)
}
}
}
// 子视图
struct ChildView: View {
@ObservedObject var viewModel: SharedViewModel
var body: some View {
Text("子视图: \(viewModel.sharedData)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
代码解释
- SharedViewModel:遵循 ObservableObject 协议,包含一个 @Published 属性 sharedData,当该属性变化时会通知视图更新。
- ParentView:使用 @StateObject 创建并管理 SharedViewModel 实例,点击按钮可更新 sharedData。
- ChildView:使用 @ObservedObject 接收从父视图传递过来的 SharedViewModel 实例,能显示和响应 sharedData 的变化。
2. 使用 @EnvironmentObject
@EnvironmentObject 能让你在整个视图层次结构中共享对象实例,无需手动在每个子视图中传递。
示例代码
import SwiftUI
import Combine
// 定义一个遵循 ObservableObject 协议的类
class SharedViewModel: ObservableObject {
@Published var sharedData: String = "初始数据"
func updateData() {
sharedData = "更新后的数据"
}
}
// 父视图
struct ParentView: View {
@StateObject private var viewModel = SharedViewModel()
var body: some View {
VStack {
Text("父视图: \(viewModel.sharedData)")
Button("更新数据") {
viewModel.updateData()
}
ChildView()
}
.environmentObject(viewModel)
}
}
// 子视图
struct ChildView: View {
@EnvironmentObject var viewModel: SharedViewModel
var body: some View {
Text("子视图: \(viewModel.sharedData)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
代码解释
- SharedViewModel:同上述示例。
- ParentView:使用 @StateObject 创建 SharedViewModel 实例,通过 .environmentObject(viewModel) 将该实例注入到视图环境中。
- ChildView:使用 @EnvironmentObject 从视图环境中获取 SharedViewModel 实例,无需手动传递。
3. 使用单例模式
单例模式可确保一个类只有一个实例,并提供一个全局访问点。
示例代码
import SwiftUI
import Combine
// 定义一个单例类
class SharedViewModel: ObservableObject {
static let shared = SharedViewModel()
private init() {}
@Published var sharedData: String = "初始数据"
func updateData() {
sharedData = "更新后的数据"
}
}
// 父视图
struct ParentView: View {
@ObservedObject private var viewModel = SharedViewModel.shared
var body: some View {
VStack {
Text("父视图: \(viewModel.sharedData)")
Button("更新数据") {
viewModel.updateData()
}
ChildView()
}
}
}
// 子视图
struct ChildView: View {
@ObservedObject private var viewModel = SharedViewModel.shared
var body: some View {
Text("子视图: \(viewModel.sharedData)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
代码解释
- SharedViewModel:通过 static let shared = SharedViewModel() 创建单例实例,private init() 确保该类不能在外部实例化。
- ParentView 和 ChildView:都通过 SharedViewModel.shared 访问同一个单例实例,实现数据共享。