使用 NSCoder 编码数组

Posted

技术标签:

【中文标题】使用 NSCoder 编码数组【英文标题】:Encode Array with NSCoder 【发布时间】:2017-02-11 06:08:16 【问题描述】:

我有一个用户Class,它在应用程序终止时使用saveuser() 方法。用户有两个Arrays 的自定义Classes 那个子类NSObject。这是我的编码方法。

func encode(with aCoder: NSCoder) 
    aCoder.encode(self.firstName, forKey: coderKey.fName)
    aCoder.encode(self.lastName, forKey: coderKey.lName)
    aCoder.encode(self.bio, forKey: coderKey.bio)
    aCoder.encode(self.tags, forKey: coderKey.tags)
    aCoder.encode(self.organizations, forKey: coderKey.orgs)
    aCoder.encode(self.img, forKey: coderKey.img)

编码self.tags 时应用程序崩溃。我认为它会对self.organizations 执行相同的操作,因为它也是NSObjectsarray,并且可能与self.img 一起使用,因为它是UIImage。这是我得到的错误。

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[Social_Justice.Tag encodeWithCoder:]:无法识别的选择器发送到实例 0x60000005efc0”

我应该怎么做才能解决这个问题?如果您需要查看更多代码,只需发表评论,我将进行编辑。

【问题讨论】:

你的两个自定义类也需要实现 NSCoding。 【参考方案1】:

正如大卫·贝瑞 (David Berry) 对原帖的评论。您必须确保您尝试编码的任何自定义类也符合 NSCoder。它们不需要存档路径,只需要具有编码和解码功能即可。

【讨论】:

【参考方案2】:

答案:

    我假设数组 self.tags 和 self.organizations 中的对象的类名是 Tag组织

    Objective-C 使用非常不同的函数调用风格。如果你看到[ClassName/ObjectName methodName],它在某种程度上等同于 Swift 中的 ObjectName.function() 样式,让我们暂时这样说(Swift 编译器将来会更好,希望你不会再看到 objctive-C 警告)调试)

    选择器是Objective-C使用的一个术语,你可以认为这是一种方法。因此,这个无法识别的选择器错误警告告诉您代码试图调用名为 encodeWithCode() 的方法,该方法实际上并不存在于对象 TagOrganization 中(NSCoder 系统知道如何对数组进行编码,但不知道如何在 Array 中编码自己的对象)

    如果你想在一个对象上使用NSCoder系统的5个具体类,对象必须符合NSCoding协议。这意味着类(TagOrganization)必须实现init?(coder: NSCoder)func encode(with: NSCoder)

    NSCoder的4个具体类是NSArchiver, NSUnarchiver, NSKeyedArchiver, NSKeyedUnarchiver, and NSPortCoder.

进一步阅读:

NSCoding / NSKeyed​Archiver By NSHipster

或者:(我最喜欢的)

Apple Document NSCoder

Apple Document NSKeyedArchiver

Apple Document NSCoding

或者:(如果这些文件对你来说还是有点困惑)

Hollemans M. 2016,ios 学徒第五版教程 2 清单,第 126 页~第 137 页

【讨论】:

以上是关于使用 NSCoder 编码数组的主要内容,如果未能解决你的问题,请参考以下文章

编码对象

iOS-NSCoder 和 NSCoding

使用 NSCoder 进行视图之间的恢复 (viewWillAppear / viewWillDisappear)

Swift 3 NSCoder 无法识别的选择器发送到实例

SKSpriteNode 在 init(NSCoder) 中设置颜色

什么时候在 UIView 或 UIViewController 上调用“required init?(coder aDecoder: NSCoder)”?