Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 保存自定义对象的数组_Ios_Arrays_Swift - Fatal编程技术网

Ios 保存自定义对象的数组

Ios 保存自定义对象的数组,ios,arrays,swift,Ios,Arrays,Swift,我正在尝试使用名为Sheet的自定义对象保存和检索notes数据。 但当它运行时,我会崩溃。这是正确的方法还是有其他方法可以解决这个问题 床单课 class Sheet { var title = "" var content = "" } 这是UITableViewController的类 class NotesListTableVC: UITableViewController { var notes = [Sheet]() override func

我正在尝试使用名为Sheet的自定义对象保存和检索notes数据。 但当它运行时,我会崩溃。这是正确的方法还是有其他方法可以解决这个问题

床单课

class Sheet {
    var title = ""
    var content = ""
}
这是UITableViewController的类

class NotesListTableVC: UITableViewController {

    var notes = [Sheet]()

    override func viewDidLoad() {
        super.viewDidLoad()

        if let newNotes = UserDefaults.standard.object(forKey: "notes") as? [Sheet] {
            //set the instance variable to the newNotes variable
            notes = newNotes
        }
    }


    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return notes.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "notesCELL", for: indexPath)

        cell.textLabel!.text = notes[indexPath.row].title

        return cell
    }

    // Add new note or opening existing note
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "editNote" {
            var noteContentVC = segue.destination as! NoteContentVC
            var selectedIndexPath = tableView.indexPathForSelectedRow
            noteContentVC.note = notes[selectedIndexPath!.row]
        }
        else if segue.identifier == "newNote" {
            var newEntry = Sheet()
            notes.append(newEntry)
            var noteContentVC = segue.destination as! NoteContentVC
            noteContentVC.note = newEntry
        }
        saveNotesArray()
    }

    // Reload the table view
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.tableView.reloadData()
    }

    // Deleting notes
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        notes.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
    }

    // Save the notes
    func saveNotesArray() {
        // Save the newly updated array
        UserDefaults.standard.set(notes, forKey: "notes")
        UserDefaults.standard.synchronize()
    }

}

我应该在哪里调用saveNotesArray函数?

您发布的代码试图将自定义对象数组保存到NSUserDefaults。你不能那样做。实现NSCoding方法没有帮助。您只能在UserDefaults中存储数组、字典、字符串、数据、数字和日期等内容

您需要将对象转换为数据(就像您在一些代码中所做的那样),并将该数据存储在UserDefaults中。如果需要,您甚至可以存储一个数据数组

在读回阵列时,需要取消归档数据以取回图纸对象

将图纸对象更改为:

class Sheet: NSObject, NSCoding {
    var title: String
    var content: String


    init(title: String, content: String) {
        self.title = title
        self.content = content
    }

    required convenience init(coder aDecoder: NSCoder) {
        let title = aDecoder.decodeObject(forKey: "title") as! String
        let content = aDecoder.decodeObject(forKey: "content") as! String
        self.init(title: title, content: content)
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(title, forKey: "title")
        aCoder.encode(content, forKey: "content")
    }
}
转化为如下函数:

func loadData() {
    if let decoded  = userDefaults.object(forKey: "notes") as? Data, let notes = NSKeyedUnarchiver.unarchiveObject(with: decoded) as? [Sheet] {
         self.notes = notes
         self.tableView.reloadData()
    }

}
然后打电话:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.loadData()
}
saveNotesArray可以在添加了以下内容的新便笺后调用:

func saveNotesArray() {
    // Save the newly updated array
    var userDefaults = UserDefaults.standard
    let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: notes)
    userDefaults.set(encodedData, forKey: "notes")
    userDefaults.synchronize()
}

您正在尝试将自定义对象数组保存为UserDefault。您的自定义对象不是这样一个对象,您不应该使用它在
UserDefaults
中保存非属性列表对象

斯威夫特4 自定义类

class Sheet: Codable {
  var title = ""
  var content = ""
}
ViewController.swift

class ViewController: UIViewController {

    var notes = [Sheet]()

    override func viewDidLoad() {
        super.viewDidLoad()

        getSheets()
        addSheets()
        getSheets()
    }
    func getSheets()
    {
        if let storedObject: Data = UserDefaults.standard.data(forKey: "notes")
        {
            do
            {
                notes = try PropertyListDecoder().decode([Sheet].self, from: storedObject)
                for note in notes
                {
                    print(note.title)
                    print(note.content)
                }
            }
            catch
            {
                print(error.localizedDescription)
            }
        }
    }
    func addSheets()
    {
        let sheet1 = Sheet()
        sheet1.title = "title1"
        sheet1.content = "content1"

        let sheet2 = Sheet()
        sheet2.title = "title1"
        sheet2.content = "content1"

        notes = [sheet1,sheet2]
        do
        {
            UserDefaults.standard.set(try PropertyListEncoder().encode(notes), forKey: "notes")
            UserDefaults.standard.synchronize()
        }
        catch
        {
            print(error.localizedDescription)
        }
    }
}

你回答了你提出的问题

应用程序崩溃日志

   [User Defaults] Attempt to set a non-property-list object ( "Sheet.Sheet" )
苹果官方信息

默认对象必须是属性列表,即(或)的实例 对于集合,是以下实例的组合:NSData、NSString、, NSNumber、NSDate、NSArray或NSDictionary

如果要存储任何其他类型的对象,通常应 将其存档以创建NSData的实例。有关详细信息,请参阅 首选项和设置编程指南

可能的解决方案之一:

class Sheet : NSObject, NSCoding{
    var title:String?
    var content:String?

    func encode(with aCoder: NSCoder) {
        aCoder.encodeObject(self.title, forKey: "title")
        aCoder.encodeObject(self.content, forKey: "content")
    }

    required init?(coder aDecoder: NSCoder) {
        self.title = aDecoder.decodeObject(forKey: "title") as? String
        self.content = aDecoder.decodeObject(forKey: "content") as? String
    }
}
拯救

装载


应用程序崩溃发生在哪里?当我尝试添加新笔记(这是一个笔记应用程序)时,按(+)按钮。尚未保存任何条目,因此没有可读取的内容。不熟悉swift,但我看不到任何方法覆盖工作表中的变量?工作表中没有任何内容暗示您可以使用可调用的所用方法保存其中的数据行,或者该工作表以某种方式继承了这些数据行?@Francis print error from logI我也不确定我是刚开始学习Swift的学生。仍然出现此错误:[用户默认值]尝试设置非属性列表对象(“Sheet.Sheet”)作为密钥注释2018-01-29 22:18:47.567973+0800页[1706:10257898]的NSUserDefaults/CFPreferences值***由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“尝试为密钥注释插入非属性列表对象(“Sheet.Sheet”),尽管这是正确且有效的(Swift 2)如果属性类型符合属性列表,则最好使用Swift 4
Codable
中的解决方案。您的代码似乎正常工作,但现在所做的更改似乎无法保存
UserDefaults.standard.set(try!PropertyListEncoder().encode(notes),forKey:“notes”)UserDefaults.standard.synchronize()
在UserDefaults中有保存数组的行。无论你想在哪里使用它。@Francis检查代码我应该遵循哪一个?上面的一张带有get和addSheets或您提供的链接?@Francis您是否在NoteContentVC中保存新便笺?
userDefaults.setValue(NSKeyedArchiver.archivedDataWithRootObject(sheets), forKey: "sheets")
sheets = NSKeyedUnarchiver.unarchiveObjectWithData(userDefaults.objectForKey("sheets") as! NSData) as! [Sheet]