一. @StateObject 数据存储机制
@StateObject 保存的数据存储在设备内存(RAM)中,是临时存储
swift
import SwiftUI
internal import Combine
class BloodGlucoseStore: ObservableObject{
@Published var count = 0 // 存储在内存中
}
struct JLHomeView: View {
@StateObject private var store = BloodGlucoseStore()// 对象存在于内存中
var body: some View {
Text("记录数量:\(store.count)")
Button("点击") {
store.count += 1
}
}
}
数据生命周期
- 创建时机:视图第一次被创建时
- 保持时机:视图重新渲染时数据保持不变
- 销毁时机:视图被销毁时数据丢失
swift
struct ContentView: View {
@State private var showHomeView = false
var body: some View {
VStack {
Button("显示/隐藏 HomeView") {
showHomeView.toggle()
}
if showHomeView {
JLHomeView() // 创建时:数据在内存中创建
} // 销毁时:数据从内存中清除
}
}
}
二. UserDefaults 存储机制
存储位置
- 📁 应用沙盒中的
.plist文件 - 路径:
/Library/Preferences/[Bundle-ID].plist
UserDefaults 数据安全性
✅ 不会丢失的情况
- 应用更新:数据保持不变
- 应用重启:数据依然存在
- 设备重启:数据保持不变
- iOS 系统更新:数据通常保持
❌ 会丢失的情况
- 卸载应用:整个应用沙盒被删除
- 恢复设备但不恢复备份:数据丢失
- 手动清除应用数据:通过系统设置清除
Swift
class SettingStore: ObservableObject{
@Published var isDarmMode: Bool{
didSet{
/// 保存数据
UserDefaults.standard.set(isDarmMode, forKey: "isDarmMode")
UserDefaults.standard.synchronize()
}
}
init(){
/// 读数数据
isDarmMode = UserDefaults.standard.bool(forKey: "isDarmMode")
}
deinit{
/// 删除数据
UserDefaults.standard.removeObject(forKey: "isDarmMode")
UserDefaults.standard.synchronize()
}
}
三. @Published 属性包装器
核心作用
@Published 的主要作用是自动触发 UI 更新
csharp
class CounterStore: ObservableObject {
var count = 0 // 普通属性
func increment() {
count += 1 // UI 不会更新!
}
}
实际应用示例
less
class BloodGlucoseStore: ObservableObject {
@Published var records: [BloodGlucoseRecord] = []
@Published var isLoading = false
@Published var errorMessage: String?
@Published var selectedDate = Date()
@Published var filterType: FilterType = .all
// 计算属性也会响应 @Published 属性的变化
var filteredRecords: [BloodGlucoseRecord] {
switch filterType {
case .all:
return records
case .today:
return records.filter { Calendar.current.isDateInToday($0.date) }
case .thisWeek:
return records.filter { $0.date.isInCurrentWeek }
}
}
func addRecord(_ record: BloodGlucoseRecord) {
records.append(record) // 触发 UI 更新
}
func setFilter(_ filter: FilterType) {
filterType = filter // 触发筛选更新
}
}
高级用法
自定义 setter
swift
class UserStore: ObservableObject {
@Published var username: String = "" {
didSet {
validateUsername()
saveToUserDefaults()
}
}
@Published var isUsernameValid = false
private func validateUsername() {
isUsernameValid = username.count >= 3
}
}
级联更新
scss
class ShoppingCartStore: ObservableObject {
@Published var items: [CartItem] = [] {
didSet {
updateTotalPrice() // items 变化时自动更新总价
}
}
@Published var totalPrice: Double = 0
@Published var discountCode: String = "" {
didSet {
updateTotalPrice() // 折扣码变化时也更新总价
}
}
private func updateTotalPrice() {
let subtotal = items.reduce(0) { $0 + $1.price * Double($1.quantity) }
let discount = calculateDiscount(for: discountCode)
totalPrice = subtotal - discount
}
}