【问题标题】:Swift 3 - NSCoding without the annoyance of inheriting from NSObjectSwift 3 - NSCoding 没有从 NSObject 继承的烦恼
【发布时间】:2016-10-06 22:32:20
【问题描述】:

从 NSKeyedArchiver 获取崩溃

2016-10-06 17:06:06.713 MessagesExtension[24473:2175316] *** NSForwarding: 
warning: object 0x61800009d740 of class '' does not implement 
methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[MessagesExtension.Model replacementObjectForKeyedArchiver:]

我创建了一个名为 Coding 的协议,其全部目的是简化 NSCodingNSKeyedArchiver,而不需要使用 Objective-C 的片段.

protocol Coding {
    static var directory: FileManager.SearchPathDirectory { get }
    static var domainMask: FileManager.SearchPathDomainMask { get }

    func encode() -> [String: AnyObject]
    init()
    init?(dict: [String: AnyObject]?)
}

extension Coding {
    static var directory: FileManager.SearchPathDirectory {
        return .documentDirectory
    }

    static var domainMask: FileManager.SearchPathDomainMask {
        return .userDomainMask
    }

    static var directoryURL: String? {
        return NSSearchPathForDirectoriesInDomains(Self.directory, Self.domainMask, true).last?.appending("/")
    }

    func save(to path: String) -> Bool {
        guard let url = Self.directoryURL else { return false }

        return NSKeyedArchiver.archiveRootObject(self.encode() as NSDictionary, toFile: url + path)
    }

    static func create(from path: String) -> Self {
        guard let url = Self.directoryURL,
              let dict = NSKeyedUnarchiver.unarchiveObject(withFile: url + path) as? [String: AnyObject] else { return self.init() }

        return self.init(dict: dict) ?? self.init()
    }
}

这个协议和扩展是为了简化 NSCoding 并允许在 Struts 上使用该协议。然而,我在尝试保存对象时遇到了上述崩溃。

更具体地说,我在

的返回线上遇到了崩溃
func save(to path: String) -> Bool {
    guard let url = Self.directoryURL else { return false }

    return NSKeyedArchiver.archiveRootObject(self.encode() as NSDictionary, toFile: url + path)
}

我感觉它与 NSDictionary 有关,但我不确定如何继续。

有什么建议吗?

【问题讨论】:

  • 您可以尝试让您的班级实现developer.apple.com/reference/objectivec/nsobject 中“归档”下的所有功能,但实际上,NSCodingNSObject 紧密耦合
  • 为什么 NSObject 不好?
  • 目标是允许对结构进行归档。如果您必须使用 NSObject,这是不可能的。
  • 这并不是真正使用NSCoding,只是获取NSKeyedArchiver的原理

标签: ios objective-c swift nscoding


【解决方案1】:

Foundation 归档系统(NSCoding 和相关类型)是很久以前为 Objective-C 设计和实现的(其中部分已有 20 多年的历史),并且期望“对象”是 @987654322 的实例@。试图用它来编码包含非NSObject-like 对象的对象图是不现实的。您可能可以简化它在 Swift 中的使用,但您需要确保归档器认为是 NSObject 的所有内容都实现了 NSObject API 的必要部分。由于没有文档说明归档器使用了哪些部分,唯一明智的选择是继承 NSObject

我当然可能是错的,但你没有向我们展示代码的相关部分(特别是 encode 的实现)。

【讨论】:

  • 这是我的问题。该协议正常工作,但我的 encode 实现有问题。我没有正确地复制字典。谢谢!
【解决方案2】:

Vishal S 撰写了一篇非常好的文章,介绍了(当前)在结构中保存数据的不同方式。

Archiving and Unarchiving Swift Structure Instances

或者如 Vishal 所说:

Swift 引入了大量的类型安全。但是,归档和取消归档总是会丢失对象的类型。除非有更好的方法通过支持 Swift 的所有原则来做到这一点,否则我们应该利用现有的资源。

当然,有人可能会建议 Apple 专家花一点精力来开发一种结构(和类型)友好的方法来保存您的数据(!)。

【讨论】:

    猜你喜欢
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    相关资源
    最近更新 更多