Ios 尝试使用用户默认值保存时出错

Ios 尝试使用用户默认值保存时出错,ios,swift,Ios,Swift,我在将表视图数据保存为用户默认值时遇到问题,我在加载函数中遇到错误“无法将类型“[String]”的值分配给类型“[ViewController.ItemRow]”。它在“items=loadedData”行给出错误。有人知道为什么它会给我这个错误吗!我不知道我是否做对了 import UIKit import SafariServices class ViewController: UIViewController, UIAdaptivePresentationControllerDeleg

我在将表视图数据保存为用户默认值时遇到问题,我在加载函数中遇到错误“无法将类型“[String]”的值分配给类型“[ViewController.ItemRow]”。它在“items=loadedData”行给出错误。有人知道为什么它会给我这个错误吗!我不知道我是否做对了

import UIKit
import SafariServices

class ViewController: UIViewController, UIAdaptivePresentationControllerDelegate, UITextFieldDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    @IBOutlet weak var OrderNumberLabel: RoundedLabel2!
    @IBOutlet weak var CostLabel: RoundedLabel2!
    @IBOutlet weak var ProfitLabel: RoundedLabel2!
    @IBOutlet weak var TotalLabel: RoundedLabel2!

    @IBOutlet weak var itemTextField: UITextField!
    @IBOutlet weak var priceTextField: UITextField!
    @IBOutlet weak var saleTextField: UITextField!

        var items: [ItemRow] = []

        struct ItemRow
        {
          var first: String
          var second: String
          var third: String
        }

        override func viewDidLoad() {
            super.viewDidLoad()
            load()
//            tableView.tableFooterView = UIView(frame: CGRect.zero)
        }


    func save(){
        UserDefaults.standard.set(items, forKey: "saved")

    }

    func load(){
        if let loadedData:[String] = UserDefaults.standard.value(forKey: "saved") as? [String]{
            items = loadedData
            tableView.reloadData()
        }

    }

    @IBAction func addButtonTapped(_ sender: Any) {
        insertNewItems()
        save()
//        profit()
//
    }

//    func profit(){
//        let priceValue = Double(priceTextField.text!)
//        let saleValue = Double(saleTextField.text!)
//
//        if priceValue != nil && saleValue != nil {
//
//            let outputValue = Double (priceValue! - saleValue!)
//
//            ProfitLabel.text = "\(outputValue)"
//            }
//    }


        func insertNewItems() {


            let newVideoRow = ItemRow(first: itemTextField.text!, second: priceTextField.text!, third: saleTextField.text!)
            items.append(newVideoRow)



            let indexPath = IndexPath(row: items.count - 1, section: 0)

            tableView.beginUpdates()
            tableView.insertRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()


            itemTextField.text = ""
            priceTextField.text = ""
            saleTextField.text = ""

            view.endEditing(true)
        }

    }





    extension ViewController: UITableViewDelegate{

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


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

             let ItemTitle = items[indexPath.row]

               let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell") as! ItemCell
               cell.itemLabel.text = ItemTitle.first
               cell.priceLabel.text = ItemTitle.second
               cell.saleLabel.text = ItemTitle.third
               return cell
        }


        func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
            return true
        }


        func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

            if editingStyle == .delete {
                items.remove(at: indexPath.row)

                tableView.beginUpdates()
                tableView.deleteRows(at: [indexPath], with: .automatic)
                tableView.endUpdates()
                save()
            }
        }
}

使结构符合
Codable
协议。这非常简单,只需将一行更改为:-

struct ItemRow : Codable
您的
保存功能可以是:-

if let data = try? PropertyListEncoder().encode(items) {
    UserDefaults.standard.set(data, forKey: "SavedItems")
}
加载
可以是:

    let defaults = UserDefaults.standard
    if let data = defaults.data(forKey: "SavedItems") {
        items = try! PropertyListDecoder().decode([ItemRow].self, from: data)
        tableView.reloadData()
    }

快速环顾四周,似乎有人认为这不应该用于大型数据集。因此,这将让您开始,但如果您需要更大量的数据(例如CoreData或Realm),则可能值得考虑一个更“数据库y”的解决方案。

您将项目保存为
struct
,而不是
string
items
[ItemRow]
,而不是
[string]
它必须是一个结构,因此如何修复可能您必须在loadedDataThread 1中以[ItemRow]而不是[String]的形式获取数据:致命错误:在load Function中的“tableView.reloadData()”行隐式展开可选值时意外发现为零,您是否已将
tableView
链接到视图控制器中的表视图(因为您不是UITableViewController的子类)?检查插座是否连接到故事板中的表视图。是的,它的链接如果您声明的错误发生在您声明的行上,则不是。请尝试使用Ctrl-Drag删除并重新链接。
tableView
是行
tableView上唯一的可选变量。重新加载数据
。我的意思是,我只是取消链接并重新链接了它,但仍然会显示出来这是一个错误