在Swift中将NSString!转换为String

14

我有一个名为name的实例变量,其类型为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!

问题是如何将温度采集并将其放入名称中?


尝试:self.name = aDecoder.decodeObjectForKey(kName) as AnyObject! as String - Maxim Shoustin
谢谢你的回答,但它仍然崩溃。 - Congruent Tech. UG
2个回答

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?。相对于as NSString!,它总是会产生一个结果(nil或有效类型值),而不会触发异常。例如,如果您希望获取字符串,但实际上传入的是一个整数,则as?会返回nil,而as NSString!则会抛出异常。
该代码还可以帮助您更好地进行调试 - 如果tempNamenil,那么要么键不存在,要么对应的值是不同类型的。

5
您可以使用Swift的nil-coalescing运算符,用一个表达式来替代您的if/else逻辑,如下所示:self.name = tempName ?? "一些初始值" - jlehr
是的,好建议。我没有仅仅为了清晰度而使用它,但我甚至都没有提到 :)。 - Antonio
谢谢您的回答。但问题似乎是从NSString!转换为String。 - Congruent Tech. UG
感谢您的回答。问题在于decodeObjectForKey似乎返回一个无法转换为字符串的NSString。因此,您建议的代码从未将值分配给名称属性。 - Congruent Tech. UG
从来没有听说过 NSString 不能被转换为 String。尝试将 decodeObjectForKey 返回的内容保存到一个 AnyObject? 变量,然后通过向下转型赋值给 tempName,并使用调试器逐行步进以查看发生了什么 - 希望这可以帮助您找出问题所在。 - Antonio

0

我需要做两件事才能让它正常工作:

  1. 清理构建并删除派生数据文件夹
  2. 由于某种原因,在这种情况下,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"
    }
    

断言会停止执行,最后一行永远不会被调用,但你需要它做什么? - HenryRootTwo
2
断言仅在调试版本中停止执行 - 这与 C 版本的语义相同。请参阅有关如何构建此内容的非常酷的博客文章 https://developer.apple.com/swift/blog/?id=4 - Andy Dent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接