我在String
中有一个实例变量名var name: String
我的类实现了NSCoding协议。所以我的名字是
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.name, forKey: kName)
}
required init(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObjectForKey(kName) as String // CRASH HERE
}
结果?我在使用解码器启动时遇到了运行时崩溃。我把init更改为:
var temp = aDecoder.decodeObjectForKey(kName) as NSString!
self.name = aDecoder.decodeObjectForKey(kName) as String
并意识到值temp保持正确的NSString值。所以我认为下面的行将解决它,但它会发出一个链接器错误:
self.name = aDecoder.decodeObjectForKey(kName) as NSString!
问题是如何把温度变成名字?
答案 0 :(得分:4)
decodeObjectForKey
会返回一个可选的AnyObject?
,因此您必须保护代码免受可能的nil值的影响。使用强制解包的强制转换听起来不安全。
我无法重现错误(因此问题可能在您的代码中的其他位置),但这是我在初始化name
属性时的方法:
var tempName = aDecoder.decodeObjectForKey("name") as? String
if let tempName = tempName {
self.name = tempName
} else {
self.name = "some initial value"
}
注意使用可选的向下转换as?
,它总是产生一个结果(nil或有效的类型值)而不是as NSString!
,如果无法进行向下转换,则会触发异常(对于实例,如果你期望一个字符串,但它是一个int而不是。)
该代码还允许您更好地调试 - 如果tempName
为nil
,则该密钥不存在或相应的值为不同类型。
答案 1 :(得分:0)
我需要做两件事才能让它发挥作用:
出于某种原因,NSString和String之间的桥接在这种情况下不起作用。所以铸造应该分两个阶段完成
if let name = aDecoder.decodeObjectForKey(kName) as? NSString {
self.name = name as String
} else {
assert(false, "ERROR: could not decode")
self.name = "ERROR"
}