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

SwiftUI中UserDefaults删除项后重启模拟器恢复问题求解

问题解决:删除ExpenseItem后UserDefaults恢复已删除项的问题

问题根源

UserDefaults的set(_:forKey:)并非实时同步到磁盘,它会在系统调度的合适时机批量写入磁盘。当你删除项后立刻终止模拟器,内存中更新的数据还没来得及完成持久化操作,下次启动时就会读取到之前未更新的缓存内容,导致已删除项“恢复”。

解决方案

方案1:强制UserDefaults同步写入

在didSet中调用synchronize()方法,强制将内存中的修改立即写入磁盘。虽然苹果文档不推荐在常规场景下使用该方法,但在需要确保即时持久化的场景下能解决问题:

didSet {
    let encoder = JSONEncoder()
    if let encoded = try? encoder.encode(items) {
        UserDefaults.standard.set(encoded, forKey: "itemsData")
        UserDefaults.standard.synchronize() // 强制同步到磁盘
    }
}

方案2:改用沙盒文件直接存储(更可靠)

相比依赖UserDefaults的异步机制,直接将数据写入沙盒中的JSON文件可以完全控制写入时机,确保修改即时持久化:

class Expenses: ObservableObject {
    @Published var items = [ExpenseItem]() {
        didSet {
            saveItems()
        }
    }
    
    // 获取沙盒中保存文件的路径
    private let savePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("items.json")
    
    init() {
        loadItems()
    }
    
    private func saveItems() {
        let encoder = JSONEncoder()
        do {
            let encoded = try encoder.encode(items)
            // 原子写入:先写临时文件,成功后替换目标文件,避免写入中断导致文件损坏
            try encoded.write(to: savePath, options: .atomicWrite)
        } catch {
            print("保存失败:\(error)")
        }
    }
    
    private func loadItems() {
        do {
            let data = try Data(contentsOf: savePath)
            let decoded = try JSONDecoder().decode([ExpenseItem].self, from: data)
            items = decoded
        } catch {
            items = []
        }
    }
}

方案3:完善错误处理(可选)

原代码中使用try?会忽略编码错误,若编码失败UserDefaults不会更新。可以添加错误处理逻辑,确保只有编码成功时才更新存储:

didSet {
    let encoder = JSONEncoder()
    do {
        let encoded = try encoder.encode(items)
        UserDefaults.standard.set(encoded, forKey: "itemsData")
        UserDefaults.standard.synchronize()
    } catch {
        print("编码失败:\(error)")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:58:20