UserDefaults 和 If/else 不稳定的行为

UserDefaults and If/else Erratic behavior

我会尽力解释我遇到的问题: 我有一个带有两个视图控制器的待办事项列表,您将在下面的代码中看到一些用于调试的打印,我添加了一个 "erase"(擦除用户默认值)并检查(检查存储在用户默认值中的内容)以进行调试

我首先使用 Erase 清除我的 userDefaults,可以看到值为 "nil"。 然后我将一个项目添加到我的列表中,例如汽车,它工作正常。 然后我添加第二个项目,比如 apple,有时它可以工作,但 90% 的时间它只是替换 car 而不是添加到数组中;我可以通过复选按钮看到它。

所以我遇到了我的第一个问题,其中 if 循环仅用打印函数替换了先前的值但我可以看到它是循环执行的第一部分,正如我在 "first" 中看到的那样控制台,所以它应该添加到数组中???

多次来自"clear";将前两项添加到我的列表中是可行的,但是从第二项开始,if 函数总是用新的替换最后一项;保留以前的。

如果我清除我的数据并为我的 UserDefaults 值获取一个 nil 值,我仍然可以看到循环的第一部分正在执行而不是 else

有时我重新启动 IOS 模拟器并得到一个不知从哪里存储的值

现在我认为 "toDo" 标识符存在错误并将所有 ID 更改为 "list" 并且只有 else 循环正在执行!!!

我不明白为什么我的代码这么乱。我希望我说得够清楚;感谢阅读

下面是我的代码(两个视图控制器;一个用于添加项目,另一个用于 tableView)

第一个ViewController

var toDoStorage = UserDefaults.standard.object(forKey: "toDo")
var toDoList = [String] ()

@IBOutlet weak var itemLabel: UITextField!
@IBOutlet weak var reportLabel: UILabel!

@IBAction func checkButton(_ sender: Any) {
    print(UserDefaults.standard.stringArray(forKey: "toDo") as Any)
}

@IBAction func eraseButton(_ sender: Any) {
    let eraseDate = ""
    UserDefaults.standard.set(eraseDate, forKey: "toDo")
    print(UserDefaults.standard.stringArray(forKey: "toDo") as Any)
   }

@IBAction func saveButton(_ sender: Any) {
    if let tempArray = toDoStorage as? [String]{
        toDoList = tempArray
        print("first")
        toDoList.append(itemLabel.text!)

    } else {
        toDoList = [itemLabel.text!]
        print("else")
    }
    UserDefaults.standard.set(toDoList, forKey: "toDo")
    itemLabel.text = ""
}

@IBOutlet weak var table: UITableView!

var toDo = UserDefaults.standard.stringArray(forKey: "toDo") ?? [String]()

public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    return toDo.count
}

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "IDCell")
    cell.textLabel?.text = String(describing: toDo[indexPath.row])
    return cell
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCellEditingStyle.delete {
        toDo.remove(at: indexPath.row)
        table.reloadData()
        UserDefaults.standard.set(toDo, forKey: "toDo")
    }
}

override func viewDidAppear(_ animated: Bool) {
    let dataCheck = UserDefaults.standard.object(forKey: "toDo")
    if let newData = dataCheck as? [String] {
        toDo = newData
        table.reloadData()
    }

答案如下(在我的新项目中将 toDo 替换为列表)

@IBAction func saveButton(_ sender: Any) {
    if UserDefaults.standard.object(forKey: "list") as? [String] != nil {
        toDoList = UserDefaults.standard.stringArray(forKey: "list")!
        toDoList.append(itemLabel.text!)

    } else {
        toDoList = [itemLabel.text!]
    }
    UserDefaults.standard.set(toDoList, forKey: "list")
    itemLabel.text = String()
    toDoList = [String] ()

首先让我吃惊的是,您正在 String[String] 之间切换,对应于 "toDo" 键的对象。

尝试将空字符串更改为空数组,即 [],看看是否可以解决一些问题。

toDo 的值是一个字符串数组。要清除 func eraseButton 中的数组,请替换

let eraseDate = ""

let eraseDate = [String]()

OURRAY 2 天后我第一次自我调试 !!! :D 所以问题主要出在两件事上的 if 语句:1)我的条件没有返回任何值,因为我没有在最后添加比较器然后 2)在第一部分我没有在添加之前更新数组。下面是新代码:

@IBAction func saveButton(_ sender: Any) {
    if UserDefaults.standard.object(forKey: "list") as? [String] != nil {
        toDoList = UserDefaults.standard.stringArray(forKey: "list")!
        toDoList.append(itemLabel.text!)
    } else {
        toDoList = [itemLabel.text!]
    }
    UserDefaults.standard.set(toDoList, forKey: "list")