2014-09-20 35 views
12

字符串我的字符串cast NSString!在迅速

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 
} 

结果?我在解码器启动时遇到了运行时崩溃。我改变了初始化为:

var temp = aDecoder.decodeObjectForKey(kName) as NSString! 
self.name = aDecoder.decodeObjectForKey(kName) as String 

并意识到价值temp是持有正确的NSString值。所以我认为,线下是要解决它,但它发出一个链接错误:

self.name = aDecoder.decodeObjectForKey(kName) as NSString! 

的问题是如何采取临时,放入名字?

+0

进行尝试:'self.name = aDecoder.decodeObjectForKey(kName)作为AnyObject!作为字符串' – 2014-09-20 08:40:09

+0

感谢您的答案,但它仍然崩溃。 – Arash 2014-09-21 06:11:36

回答

4

decodeObjectForKey返回一个可选的AnyObject?,所以你必须保护你的代码免受可能的零值。使用强制转换打开并不安全。

我无法重现错误(所以这个问题可能是你的代码别的地方),但是这是初始化name属性时,我将如何处理:

var tempName = aDecoder.decodeObjectForKey("name") as? String 
    if let tempName = tempName { 
     self.name = tempName 
    } else { 
     self.name = "some initial value" 
    } 

注意可选的使用downcasting as?,它总是产生一个结果(无或有效的类型值),而不是as NSString!,如果downcast不可能触发异常(例如,如果您期待一个字符串,但它是一个int)。

该代码还可以让您更好地进行调试 - 如果tempNamenil,那么密钥不存在或者对应的值是不同的类型。

+4

你可以使用Swift的nil-coalescing运算符来替换你的if/else逻辑,如下所示:'self.name = tempName ?? “一些初始值”' – jlehr 2014-09-20 16:13:33

+0

是的好建议。我没有使用它只是为了清晰,但我什至没有提到:) – Antonio 2014-09-20 16:41:03

+0

谢谢你的答案。但问题似乎是从NSString投射!字符串。 – Arash 2014-09-21 06:12:39

0

有两件事情,我需要做的就是它的工作:

  1. 干净的构建与删除导出的数据文件夹
  2. 有关的NSString和字符串之间某种原因桥接不能在这种情况下工作。所以铸件应分两个阶段

    if let name = aDecoder.decodeObjectForKey(kName) as? NSString { 
        self.name = name as String 
    } else { 
        assert(false, "ERROR: could not decode") 
        self.name = "ERROR" 
    } 
    
+0

assert halts execution ,最后一行永远不会被调用,但是你需要什么? – HenryRootTwo 2014-10-16 19:28:51

+2

断言只在调试版本中暂停执行 - 它与C版本的语义相同。查看非常酷的博客文章,了解他们如何构建https://developer.apple.com/swift/blog/?id=4 – 2015-06-15 03:45:51