所以我正在阅读本教程,并且我终于找到了如何使用NSCoding归档对象,以及使用可用的初始化程序再次从文件系统初始化它。
// To encode the object in the first place
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
}
// To 're-initialize' the object
required init?(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObject(forKey: "name") as! String
super.init()
}
但是,我仍然不太确定整个过程如何在高水平上运作。请告诉我我的想法不正确。
1)如果您的对象采用NSCoding协议,您可以使用encode(with :)函数,以便让NSCoder对象通过该函数并执行'编码'方法,将对象的实例属性(对象本身)作为第一个参数传递,将表示键的字符串作为第二个值传递。
2)这是一个递归过程,基本上,你传递对象的实例属性(即名称)的原因是,可以向编码消息发送THAT属性(它是一个对象),等等,直到它不再到达NSCoding采用者。
3)aDecoder对象也可以对事物进行解码,因此在初始化自定义对象时,您将希望使用可用的初始化程序来解码为您使用的模糊字符串键设置的任何对象。
这是我真正不理解的......
aDecoder对象如何知道要用于该组键的单个对象?例如,让我说我有10个狗对象实例。当系统通过一个解码器,并且我在其上使用decodeObject方法,并且它通过键将self.name设置为该解码对象的值时,aDecoder如何知道该狗的名称被保存为&#34杰克",而不是意外地抓住其中一个狗实例的名字,例如" Jodi"?
换句话说,一旦对对象的属性进行编码,文件系统如何知道将对象实例A的属性与对象实例B的属性分开,从而这样做,当应用程序启动备份并且对象A被初始化时,它只获取对象A的属性?
由于
答案 0 :(得分:1)
我认为你丢失的那篇文章(如果我错了,请纠正我)是NSCoding不是数据库。它是一个定义序列化对象的方法的协议。
用于解码的NSCoder知道哪个对象,因为那是被编码到其中的对象。例如,如果您使用NSKeyedArchiver(NSCoder子类,以及使用NSCoding的常用方法)将Dog保存到名为“/tmp/jack.dog”的磁盘上的文件,那么您以后可以使用NSKeyedUnarchiver加载“ /tmp/jack.dog“,并将其反序列化为Dog实例。它“知道哪个对象”,因为那是(唯一的)保存到该文件的对象。
它不一定是文件。数据可以保存anywhere at all。
答案 1 :(得分:1)
因此,您实际上可以通过调用class func archivedData(withRootObject rootObject: Any) -> Data'
来使用键控归档器,向其传递一些对象并返回Data
的实例,然后您可以将其保存到磁盘。
那是什么数据?它是传入的对象rootObject
的表示,其中包括对象类的名称以及一组键和关联值(其中这些关联值的编码类似)。因此,它是对象图的分层表示,带有关联的对象数据。
假设该对象是您的Dog
实例,它知道该类以及所有相关的狗属性。
相反,该对象是一个包含10个Dog
个实例的数组,现在该数组将存储一组编码对象与其索引,每个编码对象知道它的类和关联的狗属性,并且编码器存储该对象根对象是一个数组。
因此,这是由编码器管理的额外数据(并由解码器使用),它允许它在传递一些数据(例如从文件中)时知道该怎么做并要求它被解码