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

自定义Sheet对象数组存取崩溃问题及saveNotesArray调用位置咨询

问题分析与解决方案:自定义Sheet对象存储UserDefaults崩溃问题

嘿,我看到你在用自定义Sheet对象存笔记到UserDefaults时崩溃了,这是个新手常遇到的问题,咱们一步步拆解解决它~

首先,当前的实现方式是不正确的,这就是崩溃的核心原因:UserDefaults并不支持直接存储自定义的Swift类对象(比如你的Sheet类),它只能存储特定类型的数据——像字符串、数字、布尔值,或者包含这些类型的数组/字典,以及遵循Codable协议的对象,或者继承自NSObject并遵循NSCoding协议的对象。你的Sheet类既没有遵循这些协议,直接把[Sheet]存入UserDefaults自然会触发崩溃。

解决方案:让Sheet类支持序列化

最简洁的方案是让Sheet类遵循Swift的Codable协议(因为你的属性都是String类型,Swift会自动为你生成序列化/反序列化的代码,不需要手动写)。

修改Sheet类代码

class Sheet: Codable {
    var title = ""
    var content = ""
}

调整保存与读取逻辑

接下来要修改保存和读取的代码,把数组编码成Data再存入UserDefaults;读取时则从Data解码回[Sheet]:

重写saveNotesArray函数

func saveNotesArray() {
    do {
        let data = try JSONEncoder().encode(notes)
        UserDefaults.standard.set(data, forKey: "notes")
        // iOS 12+之后synchronize()已废弃,系统会自动处理同步
        // UserDefaults.standard.synchronize()
    } catch {
        print("保存笔记失败:\(error.localizedDescription)")
    }
}

调整viewDidLoad中的读取逻辑

override func viewDidLoad() {
    super.viewDidLoad()
    if let data = UserDefaults.standard.data(forKey: "notes") {
        do {
            notes = try JSONDecoder().decode([Sheet].self, from: data)
        } catch {
            print("读取笔记失败:\(error.localizedDescription)")
        }
    }
}

saveNotesArray函数应该调用的位置

你需要在笔记数据发生变化的所有场景调用这个函数,确保数据及时保存:

  • 删除笔记后:在删除逻辑的末尾添加调用,因为数组已经被修改
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        notes.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .automatic)
        saveNotesArray() // 添加这行保存操作
    }
    
  • 用户编辑完笔记返回后:因为Sheet是引用类型,用户在NoteContentVC里修改的内容会直接同步到notes数组中,所以可以在viewWillAppear里调用保存,确保每次页面显示时都保存最新状态
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.tableView.reloadData()
        saveNotesArray() // 添加这行
    }
    
  • 移除当前prepare中的无效调用:你现在在prepare(for:sender:)里调用了saveNotesArray,但这时候新笔记还没被编辑,内容是空的,这个调用没有意义,建议删掉。

另外,如果你的NoteContentVC有明确的“保存”按钮,也可以在用户点击该按钮时直接触发保存逻辑,这样更精准。

额外提示

  • UserDefaults适合存储小量数据,如果你的笔记数量多、内容长,建议改用Core Data、Realm或者本地文件存储,UserDefaults并不是为大量数据设计的。
  • 记得移除UserDefaults.standard.synchronize(),这个方法在iOS 12之后已经被废弃,系统会自动处理UserDefaults的同步操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:52:22