本文主要讲解在单例模式下的两种管理共享数据方法。
前提内容为,在Xcode项目中设置了一个管理类以及创建全局单例,这部分内容与《iOS将@AppStorage同步到iCloud》文章重叠,如果需要了解管理共享数据部分,可以查看前文。
管理方法
1、使用 @StateObject 或 @ObservedObject + .environmentObject
在 @main 入口文件或 ContentView 中创建 @StateObject 并通过 .environmentObject() 传递。
子视图使用 @EnvironmentObject 获取数据。
// AppStorageManager.swift
import SwiftUI
import Combine
class AppStorageManager: ObservableObject {
static let shared = AppStorageManager() // 单例
@Published var someData: String = "初始数据"
}
// MyApp.swift
@main
struct MyApp: App {
@StateObject private var appStorage = AppStorageManager.shared
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(appStorage)
}
}
}
// ContentView.swift
struct ContentView: View {
var body: some View {
ChildView()
}
}
// ChildView.swift
struct ChildView: View {
@EnvironmentObject var appStorage: AppStorageManager
var body: some View {
VStack {
Text(appStorage.someData)
Button("更新数据") {
appStorage.someData = "数据已更新"
}
}
}
}
优点
@EnvironmentObject 可以自动在子视图中获取数据,无需手动传递。
数据变更时,所有使用该数据的视图都会自动刷新。
适用场景
数据需要在多个视图之间共享,并且涉及跨层级数据流时。
需要确保数据一致性,避免多次实例化导致数据不同步。
2、在子视图中直接使用 AppStorageManager.shared
实现方法
直接在子视图中声明 var appStorage = AppStorageManager.shared 并使用。
// ChildView.swift
struct ChildView: View {
var appStorage = AppStorageManager.shared
var body: some View {
VStack {
Text(appStorage.someData)
Button("更新数据") {
appStorage.someData = "数据已更新"
}
}
}
}
优点
简单直接,不需要通过 .environmentObject() 传递数据。
适用于数据作用域仅限于某个视图或少量视图时。
注意事项
如果在多个视图中直接使用 AppStorageManager.shared,且数据更新时,可能会有视图无法自动刷新的问题,除非手动刷新或绑定。
不适合跨多个层级或大量子视图的复杂场景。
推荐选择
如果数据需要跨多个视图共享或全局管理使用 @StateObject + .environmentObject。
如果数据只在某个局部视图或简单视图中使用直接使用 AppStorageManager.shared。
一般来说,大多数情况下 @EnvironmentObject 的方式更推荐,因为它更具灵活性,并且能确保数据一致性。
相关文章
- iOS将@AppStorage同步到iCloud:https://fangjunyu.com/2025/03/01/ios%e5%b0%86appstorage%e5%90%8c%e6%ad%a5%e5%88%b0icloud/
- Swift控制全局的单例模式:https://fangjunyu.com/2024/10/19/swift%e6%8e%a7%e5%88%b6%e5%85%a8%e5%b1%80%e7%9a%84%e5%8d%95%e4%be%8b%e6%a8%a1%e5%bc%8f/
- Swift 单例模式下的视图关系:https://fangjunyu.com/2024/10/25/swift-%e5%8d%95%e4%be%8b%e6%a8%a1%e5%bc%8f%e4%b8%8b%e7%9a%84%e8%a7%86%e5%9b%be%e5%85%b3%e7%b3%bb/