【问题标题】:How do I encode [Character : Int] property using NSCoder in Swift 3?如何在 Swift 3 中使用 NSCoder 对 [Character : Int] 属性进行编码?
【发布时间】:2017-09-04 01:51:45
【问题描述】:
import UIKit

class Foo: NSObject, NSCoding {
    var cx: [Character : Int]

    init(cx: [Character : Int]) {
        self.cx = cx
    }

    // MARK: - <NSCoding>

    required convenience init(coder aDecoder: NSCoder) {
        let cx = aDecoder.decodeObject(forKey: "cxKey") as! [Character : Int]
        self.init(cx: cx)
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(cx, forKey: "cxKey")
    }
}

调用:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var foo = Foo(cx: ["C": 5, "X": 6])

        let encodedData = NSKeyedArchiver.archivedData(withRootObject: foo)
        print("encodedData: \(encodedData))")

        if let foo1 = NSKeyedUnarchiver.unarchiveObject(with: encodedData) as? Foo {
            print("cx = ", foo1.cx)
        } else{
            print("There is an issue")
        }
    }
}

Xcode 抛出错误:*** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance

【问题讨论】:

  • 你怎么称呼它?
  • 抱歉,已添加

标签: ios swift3 nscoding


【解决方案1】:

原因

这是因为cx 中的Character 类型的键将被装箱为_SwiftValue 对象,这些对象将被发送encodeWithCoder:,从而导致无法识别的选择器异常。

查看SwiftValue.h顶部的评论:

这实现了用于承载Swift的Objective-C类 已经桥接到 Objective-C 对象的值,没有特殊的 处理。该类对用户代码不透明,但为 NSObject- 和 NSCopying- 符合并被 Swift 运行时理解为 动态转换回包含的类型。

解决方案

如果您可以将cx 的类型更改为[String : Int],那么一切都将开箱即用(没有双关语)。

否则,您必须在解码初始化程序中将 Foo.encode(with:) 中的 cx 转换为可编码的内容(例如 [String : Int]),反之亦然。

有关一些代码,请参阅 How do I encode Character using NSCoder in swift? 和 How do I encode enum using NSCoder in swift?。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    相关资源
    最近更新 更多