swift:nscoding decodeObject始终为nil

use*_*552 11 nscoding ios nskeyedunarchiver multipeer-connectivity swift

我在写一个名为Packet的对象时得到了以下代码,并通过Multipeer连接发送到另一端.但是,每当它尝试解码编码对象时,我都会收到以下错误.

  class Packet : NSObject, NSCoding {

  var tmp1: Double = 0
  var tmp2: Double = 0

  struct PropertyKey {
    static let tmp1Key = "tmp1Key"
    static let tmp2Key = "tmp2Key"
  }


  init(tmp1: Double, tmp2: Double) {
    self.tmp1 = tmp1
    self.tmp2 = tmp2
    super.init()
  }

  deinit {
  }

  required convenience init(coder aDecoder: NSCoder) {
    debugPrint("initcoder")
    let tmp1 = aDecoder.decodeObject(forKey: PropertyKey.tmp1Key) as! Double // crash here
    let tmp2 = aDecoder.decodeObject(forKey: PropertyKey.tmp2Key) as! Double
    self.init(tmp1: tmp1, tmp2: tmp2)
  }

  public func encode(with aCoder: NSCoder) {
    debugPrint("encodeCoder")
    aCoder.encode(tmp1, forKey: PropertyKey.tmp1Key)
    aCoder.encode(tmp2, forKey: PropertyKey.tmp2Key)
  }
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是----从我打印----"initcoder"致命错误:在展开可选值时意外发现nil 2016-09-30 13:32:55.901189连接[323:33022]致命错误:在展开Optional值时意外地发现了nil

但是当我构造对象时,所有的值都被设置了.我没有问题收缩了Packet对象.

----附加信息------当通过乘法器连接发送到另一侧时,我使用以下代码对数据进行编码和解码.

 func dataForPacket(packet: Packet) -> Data {
    let data = NSMutableData()
    let archiver = NSKeyedArchiver(forWritingWith: data)
    archiver.encode(packet, forKey: "Packet")
    archiver.finishEncoding()
    debugPrint("dataForPacket \(data) \(packet)")
    return data as Data
  }

  func packetForData(_ data: Data) -> Packet {
    debugPrint("packetForData")
    let unarchiver = NSKeyedUnarchiver(forReadingWith: data)

    let packet: Packet = unarchiver.decodeObject(forKey: "Packet") as! Packet 
     // crash here (as this will call the init of the Packet class)
    debugPrint("packetForData \(packet)")
    return packet
  }
Run Code Online (Sandbox Code Playgroud)

我想知道什么可能导致错误.谢谢.

Nal*_*ene 13

斯威夫特3:

我正在编码一个双值.使用decoder.containsValue检查值是否已编码.

并使用decodeDouble(forKey :).不是decodeObject(forKey :)

 var dateTime: TimeInterval = SOME_TIME_INTERVAL (Double)//Can be saved(encoded) previously, and not encoded as well.
 aCoder.encode(dateTime, forKey: "dateTime")
 if decoder.containsValue(forKey: "dateTime") {
            dateTime = decoder.decodeDouble(forKey: "dateTime")
        }
Run Code Online (Sandbox Code Playgroud)


小智 5

斯威夫特 4.2:

decodeObject(forKey:)用于解码原始类型时,它返回 nil。因为 的重载encode(_:forKey:)直接拿一个 Int 写成 NSNumber 类型,你不能把它解码成一个对象。

decodeInteger(forKey:)将其作为 Int 正确读出并返回。您可以使用decodeInteger(forKey:),Int(decodeInt32(forKey:))Int(decodeInt64(forKey:))代替。