在viewDidLoad崩溃中调用函数

时间:2016-08-01 17:34:28

标签: ios swift optional viewdidload

调用parseString会导致我的应用程序崩溃。 myOptionalString已在tableview中从didSelectRowAtIndexPath设置。信息肯定会传递给这个视图控制器。

如果按下按钮调用该方法也有效。但是在任何生命周期方法中,我尝试在解开Optional时意外地发现nil。

override func viewDidLoad() {
    super.viewDidLoad()   
    if let myUnwrappedString = myOptionalString{
         print(myUnwrappedString) //<-- prints out string
         confidence.text = parseString(myUnwrappedString) //<-- unexpectedly found nil while unwrapping an Optional crash
    }        
}

//this method works if called on a button press but crashes in viewDidLoad
func parseString(myString: String)->String{
    return myString.substringFromIndex(myString.rangeOfString(" ")!.endIndex)
}

2 个答案:

答案 0 :(得分:3)

您的错误来自您的函数parseString,让我们看看为什么。如果您仔细查看了您的功能,那么您可以在myString.rangeOfString(" ")!的情况下对可选值进行强制展开。根本不建议这样做。

如果我们将字符串"Confidence: 63%"传递给函数,则函数正常工作并返回"63%",但它可以工作,因为它里面有" "字符串,如果由于某种原因你传递了一些没有它的字符串会崩溃(例如"Confidence:63%")。

因此,实现此功能的正确方法之一是使用guard语句,使用可选绑定,避免任何强制解包

func parseString(myString: String) -> String? {
   guard let range = myString.rangeOfString(" ") else { return nil }
   return myString.substringFromIndex(range.endIndex)
}

在上面的函数中,如果字符串中不存在nil,则返回" "并避免运行时错误。

我希望这对你有所帮助。

答案 1 :(得分:0)

我猜你的问题在于这一行:

myString.rangeOfString(" ")!

rangeOfString返回一个可选的Range<Index>?值,这意味着如果您要查找的字符不在字符串中,您将获得值nil作为回报。换句话说,如果字符串中没有空格,则会为您的范围获得nil值。

然后用!强行打开该值,然后用它来调用substringFromIndex。这意味着如果范围实际上是nil,则使用该nil值来尝试从其endIndex创建一个子字符串...您不能......因此它会崩溃。 / p>

解决此问题的一种方法是使用guard来确保您确实在字符串中找到了一个范围。如果你没有,那么你只需返回一个空的String ...或者做一些更适合你的用例的事情。

以下是一个例子:

func parseString(myString: String)->String{
    guard let range = myString.rangeOfString(" ") else {
        return ""
    }
    return myString.substringFromIndex(range.endIndex)
}

希望对你有所帮助。