【发布时间】:2017-02-08 14:50:24
【问题描述】:
我得到以下代码来编写一个名为 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)
}
}
我得到的错误是 ----从我这里打印出来----“initcoder” 致命错误:在展开可选值时意外发现 nil 2016-09-30 13:32:55.901189 Connection[323:33022] 致命错误:在展开可选值时意外发现 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
}
我想知道什么会导致错误。谢谢。
【问题讨论】:
-
你需要使用decodeDouble作为key
-
let tmp1 = aDecoder.decodeDouble(forKey: PropertyKey.tmp1Key) -
正如上述 cmets 所提到的,您必须对整数、浮点数、布尔值、双精度数等使用特定的解码。
-
非常感谢!!它解决了我的问题!
-
我发现了另一个问题:当我的类 Packet 具有其他类型的类变量(例如,数组、UIViews)时,我对 tmp1 和 tmp2 使用了 decodeDouble,然后对其他类型使用了 decodeObject。然后它崩溃并说 tmp1 和 tmp2 不是 Double 类型(虽然它们实际上是 Double 类型)。当我将它们更改为 decodeObject 时,它不再崩溃。为什么会这样?
标签: ios swift nscoding multipeer-connectivity nskeyedunarchiver