我有一个UIView子类,其中包含以下内容:
class someClass: UIView {
var someString = ""
var imageView: UIImageView
var position: CGPoint
var dimensions: CGFloat
init(position: CGPoint, dimensions: CGFloat, someString: String) {
self.position = position
self.dimensions = dimensions
self.someString = someString
self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: dimensions, height: dimensions))
super.init(frame: CGRect(x: position.x, y: position.y, width: dimensions, height: dimensions))
addSubview(imageView)
}
}
我还添加了required init?(coder aDecoder: NSCoder)
和encodeWithCoder(coder: NSCoder)
:
required init?(coder aDecoder: NSCoder) {
self.someString = aDecoder.decodeObject(forKey: "someString") as! String
self.position = aDecoder.decodeObject(forKey: "position") as! CGPoint
self.dimensions = aDecoder.decodeObject(forKey: "dimensions") as! CGFloat
self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: dimensions, height: dimensions))
super.init(frame: CGRect(x: position.x, y: position.y, width: dimensions, height: dimensions))
self.addSubview(imageView)
}
func encodeWithCoder(coder: NSCoder) {
coder.encode(self.position, forKey: "position")
coder.encode(self.dimensions, forKey: "dimensions")
coder.encode(self.someString, forKey: "someString")
}
所以,我创建了一个类的对象:
let someObject = someClass(position: CGPoint(x: 2.0, y: 3.0), dimensions: 10.0, someString: "Hello")
我正在尝试存档该对象:
let archivedObject = NSKeyedArchiver.archivedData(withRootObject: someObject)
然后取消归档:
let unarchivedObject = NSKeyedUnarchiver.unarchiveObject(with: archivedObject) as! someClass
我收到错误:
如果打印unarchivedObject,那将是“致命错误:在展开可选值时意外地发现nil”。
有人可以帮我这个吗?有什么问题?
答案 0 :(得分:1)
看起来问题是你没有正确地覆盖encodeWithEncoder
。如果你在该函数中放置一个断点,你会发现它永远不会被调用,这就是当你尝试解码它时对象为零的原因 - 它永远不会被编码!
尝试在CGPoint上使用decodeObject
时也会遇到错误。确保更改该行,然后您应该开展业务。
顺便说一下,通常的做法是将类名称大写,以便它们与该类的实例不同,因此我将someClass
更改为SomeClass
。
class SomeClass: UIView {
var someString = ""
var imageView: UIImageView
var position: CGPoint
var dimensions: CGFloat
init(position: CGPoint, dimensions: CGFloat, someString: String) {
self.position = position
self.dimensions = dimensions
self.someString = someString
self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: dimensions, height: dimensions))
super.init(frame: CGRect(x: position.x, y: position.y, width: dimensions, height: dimensions))
addSubview(imageView)
}
required init?(coder aDecoder: NSCoder) {
self.someString = aDecoder.decodeObject(forKey: "someString") as! String
self.position = aDecoder.decodeCGPoint(forKey: "position")
self.dimensions = aDecoder.decodeObject(forKey: "dimensions") as! CGFloat
self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: dimensions, height: dimensions))
super.init(frame: CGRect(x: position.x, y: position.y, width: dimensions, height: dimensions))
self.addSubview(imageView)
}
override func encode(with aCoder: NSCoder) {
aCoder.encode(self.position, forKey: "position")
aCoder.encode(self.dimensions, forKey: "dimensions")
aCoder.encode(self.someString, forKey: "someString")
}
}