【问题标题】:Using User Default only, but display reason: 'Attempt to insert non-property list object [duplicate]仅使用用户默认值,但显示原因:'尝试插入非属性列表对象 [重复]
【发布时间】:2018-03-10 11:42:28
【问题描述】:
import UIKit

struct Task {
    var name: String
    var completed: Bool
}

class ListModel {

    var tasks: [Task] = [] // array to store tasks of todo list

    let defaluts = UserDefaults.standard

    func addTask( name: String, completed: Bool ) {   // store task with status of complete into array
        self.tasks.append( Task( name: name, completed: completed ) )
    }

    var tasksValue: [Task] { // getter and setter of array tasks
        get {
            return tasks
        }
        set {
            tasks = newValue
        }
    }

    func save() {
        defaluts.set(tasks, forKey: "tasks")
    }

    func load() {
        if let value = defaluts.array(forKey: "tasks") as? [Task] {
            tasks = value 
        }
    }
}

当我运行我的程序时,它显示由于未捕获的异常“NSInvalidArgumentException”而终止应用程序的错误,原因:“尝试插入非属性列表对象。

有人可以帮我解决吗?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    答案很简单。您只能保存一小部分数据类型(属性列表类型:Array、Dictionary、String、Data、Date、Int、Double、Float、Bool ) 到UserDefaults 或属性列表。

    如果您尝试编写任何其他对象类型或包含任何其他类型的容器,则会失败。您需要将自定义对象序列化为其他类型。

    另外,除了小的用户设置值之外,您不能将任何内容存储到默认值。

    【讨论】:

    • 感谢您的建议,我可以将数组拆分为两种类型对吗?我的意思是,数组的类型是Task,它是struct,但我只能在带有UserDefaults的struct中使用String和Bool,对吧?
    • 可能最好的解决方案是让您的自定义对象符合 NSCoding,然后您可以将整个对象数组直接保存到属性列表中。
    • 谢谢,我会努力解决的
    • 请注意,如果您使用的是 Swift 4(您应该用于新开发),您可以让您的对象符合 Coding 协议,然后使用 JSONEncoder/JSONDecoder(对 JSON 进行编码/解码)或 PropertyListEncoder/PropertyListDecoder(编码/解码为属性列表。)
    • 如果你的对象的所有属性都是简单类型,或者属性是简单类型的自定义类型,你可以使用新的编码协议序列化/反序列化你的对象 no 自定义代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2022-01-09
    相关资源
    最近更新 更多