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

UIKit+Storyboard TodoList:解决已删任务添加新任务后恢复问题

解决TodoList滑动删除后任务自动恢复的问题

嘿,我看了你的代码,问题出在删除任务时没有正确同步更新UserDefaults里的存储数据,再加上你当前用count+单个task_xxx键的存储方式本身就容易出数据不一致的问题,才导致添加新任务时已经删掉的任务又回来了。

先拆解下你现有代码里的问题点:

  1. 删除方法里的逻辑混乱:你先从内存的tasks数组删掉了元素,然后又做了先把数组存到UserDefaults、立刻又删掉这个键的无效操作,完全没更新原来用来存储任务的count和task_1/task_2这类键值对。
  2. updateTasks()方法是从count和task_xxx键读取数据的,删除后这些旧数据还留在UserDefaults里,添加新任务时count递增,之前没删干净的旧任务就会被重新加载回来。

修复方案:改用数组直接存储到UserDefaults

与其拆分存储,不如直接把整个任务数组存在UserDefaults里,这样增删改查的逻辑都会简单很多,也不容易出错。下面是具体的修改步骤:

1. 简化数据加载逻辑(修改ViewController的updateTasks方法)

把原来从count和单个task_xxx读取数据的逻辑,改成直接读取整个数组:

func updateTasks() {
    // 读取存储的任务数组,为空的话返回空数组
    tasks = UserDefaults.standard.array(forKey: "tasks") as? [String] ?? []
    tableView.reloadData()
}

2. 修复删除任务的逻辑

删除任务时,同步更新内存数组和UserDefaults,还可以加上删除动画提升体验:

// タスクを削除
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    guard editingStyle == .delete else { return }
    
    // 1. 从内存数组删除对应任务
    tasks.remove(at: indexPath.row)
    // 2. 同步更新到UserDefaults
    UserDefaults.standard.set(tasks, forKey: "tasks")
    // 3. 用动画删除表格行(比reloadData更流畅)
    tableView.deleteRows(at: [indexPath], with: .automatic)
}

3. 修改添加任务的逻辑(EntryViewController的saveTask方法)

原来基于count的添加逻辑可以删掉,改成直接操作数组:

@objc func saveTask() {
    guard let text = field.text, !text.isEmpty else { return }
    
    // 1. 读取现有任务数组
    var currentTasks = UserDefaults.standard.array(forKey: "tasks") as? [String] ?? []
    // 2. 添加新任务
    currentTasks.append(text)
    // 3. 存回UserDefaults
    UserDefaults.standard.set(currentTasks, forKey: "tasks")
    // 4. 通知主页面刷新
    update?()
    navigationController?.popViewController(animated: true)
}

4. 清理初始化代码

ViewController里原来关于setup和count的初始化代码已经没用了,可以删掉,简化成:

override func viewDidLoad() {
    super.viewDidLoad()
    self.title = "リスト"
    tableView.delegate = self
    tableView.dataSource = self
    updateTasks()
}

补充解答你的疑问

  • remove(at:)有没有问题?:这个方法本身是正确的,它能正确删除内存数组里的元素,问题出在你没有把这个删除操作同步到UserDefaults的存储中,导致下次加载时旧数据又被读回来了。
  • 如何正确保存UserDefaults?:对于集合类型(比如数组、字典),直接存储整个集合是更可靠的方式,避免拆分存储带来的索引混乱、数据不一致问题。每次修改数据后,都要把更新后的集合重新存回UserDefaults,确保内存和本地存储的数据一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:52:33