You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI全局变量Quarters无法自增且需应用关闭后持久存储如何解决

问题根因

你的代码存在两个核心问题:

  • MyVariables中定义的quarters是实例属性,你没有创建该结构体的实例,直接通过类型名访问属性本身不符合语法逻辑;即使你添加static关键字将其改为静态属性,也会触发第二个问题
  • SwiftUI的视图刷新依赖内置的状态标记源,普通全局/静态属性值变化时,不会通知视图触发重绘,所以即使值已经修改,界面上的文本也不会更新,看起来就像值始终停留在0
实现方案

你要的全局可访问、改动自动刷新视图、App重启后保留值的能力,可以直接通过@AppStorage+单例ObservableObject实现,代码如下:

import SwiftUI
// 全局状态管理类
class QuarterState: ObservableObject {
    // 全局唯一单例,保证全App所有模块访问的是同一个对象
    static let shared = QuarterState()
    // @AppStorage 自动负责UserDefaults持久化,改动时自动通知所有监听的视图刷新
    @AppStorage("quarters") var quarters = 0
    // 私有化构造方法,禁止外部创建新实例,保证单例唯一性
    private init() {}
}

视图层调用方式:

struct ContentView: View {
    // 引用全局单例,标记为@StateObject监听状态变化
    @StateObject private var quarterState = QuarterState.shared
    
    var body: some View {
        VStack {
            Text("\(quarterState.quarters)").bold()
            Button(action: {
                quarterState.quarters += 1
            }) {
                Image("QuarterMachine")
            }
        }
    }
}

如果你需要用到自己写的Storage协议实现持久化逻辑,修改全局状态类即可:

class QuarterState: ObservableObject {
    static let shared = QuarterState()
    private let storage: Storage = LocalStorage()
    // @Published 标记属性改动时通知视图刷新
    @Published var quarters = 0
    
    private init() {
        // 初始化时从本地读取存储的值
        quarters = storage.quarters
    }
    
    // 对外提供操作方法,保证改动时同时更新内存值和本地存储
    func addQuarter() {
        quarters += 1
        storage.save(quarters: quarters)
    }
    
    func resetQuarters() {
        quarters = 0
        storage.save(quarters: 0)
    }
}

此时按钮点击的action替换为调用quarterState.addQuarter()即可。
在App其他任意位置需要读写quarters值时,直接调用QuarterState.shared.quarters即可,所有监听该状态的视图都会自动同步最新值。


内容的提问来源于stack exchange,提问作者sUnit1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 23:15:05