用户默认值从Obj C迁移到Swift

数数

我工作的Update我的OS X应用程序,它最初是写在Obj-C
更新已被写入Swift


我遇到了一个用户默认值处理的奇怪问题。(因为用户首选项不能在更新中更改)

所有本机类型(例如Bool, String)的用户首选项都可以正常工作,但是NSCoding符合标准的Class不能deserialse / Unarchive它给出了一个错误:

Error :[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (KSPerson) for key (NS.objects); the class may be defined in source code or a library that is not linked

我进行了以下尝试,但仍然无法找出解决方案

  1. 起初,我认为这是由于不同的类名(在SwiftPerson代替KSPerson)。但是更改类名(返回KSPerson)并不能解决问题
  2. 为了使课堂Objective C更像我也尝试过@objc

这是代码

let UD = NSUserDefaults.standardUserDefaults()

func serialize() {
    // Info: personList: [KSPerson]
    let encodedObject: NSData = NSKeyedArchiver.archivedDataWithRootObject(personList)
    UD.setObject(encodedObject, forKey: "key1")
    print("Serialization complete")
}

func deserialise() {
    let encodedObject: NSData = UD.objectForKey("key1") as! NSData
    let personList: [KSUrlObject] = NSKeyedUnarchiver.unarchiveObjectWithData(encodedObject) as! [KSPerson]

    for person in personList {
        print(person)
    }

注:
我创建了一个duplicate copyObjective C代码,并deserialised完美(什么是由原件连载)。
出乎我的意料。当我重新命名类KSPersonJSPersonduplicate copy上面看到它给我确切的同样的错误

所以一件事很清楚。您需要具有与UnarchiveNSCoding兼容的相同的类名objects但这显然不足以Swift

罗布·纳皮尔

Swift类包括其模块名称。Objective-C类没有。因此,当您取消归档Objective-C类“ KSPerson”时,Swift将遍历所有类并找到“ mygreatapp.KSPerson”,并得出结论,它们不匹配。

您需要告诉取消归档的人如何将归档名称映射到模块的类名称。您可以使用以下命令集中执行此操作setClass(_:forClassName:)

NSKeyedUnarchiver.setClass(KSPerson.self, forClassName: "KSPerson")

这是全局注册,适用于所有不覆盖它的未归档程序。当然,您可以为同一类注册多个名称以进行存档。例如:

NSKeyedUnarchiver.setClass(KSPerson.self, forClassName: "KSPerson")
NSKeyedUnarchiver.setClass(KSPerson.self, forClassName: "mygreatapp.Person")
NSKeyedUnarchiver.setClass(KSPerson.self, forClassName: "TheOldPersonClassName")

编写Swift档案时,默认情况下它将包含模块名称。这意味着,如果您曾经更改模块名称(或在一个模块中归档而在另一个模块中取消归档),则将无法取消归档数据。这样做有一些好处(可以防止意外将其归档为错误的类型),但是在许多情况下,您可能不希望这样做。如果没有,您可以通过在另一个方向注册映射来覆盖它:

NSKeyedArchiver.setClassName("KSPerson", forClass:KSPerson.self)

这仅影响注册后归档的类。它不会修改现有档案。

这仍然很脆弱。unarchiveObjectWithData:遇到问题时会引发ObjC异常,而Swift无法捕获。您将因坏数据而崩溃。您可以避免使用-decodeObjectForKey而不是+unarchiveObjectWithData

let encodedObject: NSData = UD.objectForKey("key1") as? NSData ?? NSData()
let unarchiver = NSKeyedUnarchiver(forReadingWithData: encodedObject)
let personList : [KSPerson] = unarchiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as? [KSPerson] ?? []

[]如果有问题而不是崩溃,则返回此值它仍然尊重全局类名注册。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Swift中保存为用户默认值

来自分类Dev

用户默认值Swift中的“预期的声明”错误

来自分类Dev

C ++默认值

来自分类Dev

Laravel迁移默认值

来自分类Dev

Swift IBoutlet默认值

来自分类Dev

在Swift 3中从用户默认值检索字符串值

来自分类Dev

迁移中的Django datetime默认值

来自分类Dev

从Rails迁移中删除默认值

来自分类Dev

Laravel迁移更改列的默认值

来自分类Dev

从迁移中的lambda指定默认值

来自分类Dev

如何在目标c中将自定义对象存储为用户默认值?

来自分类Dev

用户单击数字时,Objective C文本字段的默认值从“•••••••”到“ 1•••••••”,“ 12•••••”,“ 123••••”

来自分类Dev

用户单击数字时,Objective C文本字段的默认值从“•••••••”到“ 1•••••••”,“ 12•••••”,“ 123••••”

来自分类Dev

Swift:可选的无用默认值?

来自分类Dev

Swift-嵌套枚举默认值

来自分类Dev

Swift2 iOS-注销当前用户并创建新用户会保留新用户的旧用户默认值

来自分类Dev

当将项目从java1.4迁移到java1.8时,jsp中TextBox的默认值为“ null”

来自分类Dev

C#Convert.ToBoolean的默认值

来自分类Dev

在C#中设置默认值

来自分类Dev

C#结构默认值

来自分类Dev

struct c中的默认值[重复]

来自分类Dev

C ++中类成员的默认值

来自分类Dev

在C#中设置默认值

来自分类Dev

turbo c 中的默认值

来自分类Dev

Rails迁移错误默认值错误

来自分类Dev

Rails迁移默认值0是否为false?

来自分类Dev

实体框架迁移从功能中插入默认值

来自分类Dev

在Rails表单输入字段中覆盖迁移默认值

来自分类Dev

Laravel迁移整数的默认值不起作用

Related 相关文章

热门标签

归档