Swift 3 - NSCoding 没有继承 NSObject 的烦恼

S.M*_*ore 2 objective-c nscoding ios swift

从 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:]
Run Code Online (Sandbox Code Playgroud)

我创建了一个名为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()
    }
}
Run Code Online (Sandbox Code Playgroud)

该协议和扩展旨在简化 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)
}
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,它与 NSDictionary 有关,但我不确定如何进行。

有什么建议??

rob*_*off 6

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

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