创建计算器应用程序

时间:2016-05-06 14:25:44

标签: swift

所以我对Swift很新,并且一直在关注本教程来制作这个应用https://www.youtube.com/watch?v=NJHsdjH2HdY

这是第一个问题:currentNumber = currentNumber * 10 + Float(sender.titleLabel!.text!.toInt()!)

在评论部分,该人说要将该行更改为: currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel!.text!)!)

我这样做了,我收到错误:线程1:EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)

1 个答案:

答案 0 :(得分:3)

如评论中所述,您应该始终避免使用'崩溃运算符' (!) - 并学会安全地处理可选值。

您的程序崩溃了,因为titleLabeltextInt(...)都是nil - 然后您正试图强行打开它们。这可能意味着您的按钮没有titleLabeltitleLabel的文字无法转换为Int

解决方案是在遇到选项时安全地处理选项。有很多方法可以做到这一点,但我通常喜欢使用一个或多个guard语句。如果它具有值,则允许您安全地展开可选项,否则它将执行括号内的代码。当未来的代码依赖于在可选的nil上时,这非常有用。例如:

guard let buttonText = sender.titleLabel?.text else {
    print("Sender didn't have either a titleLabel or text!")
    return
}

guard let textAsInt = Int(buttonText) else {
    print("Text wasn't convertible to an Int!")
    return
}

currentNumber = currentNumber*10 + Float(textAsInt)

现在,您可以获得有用的print消息,而不是崩溃!因此,您确切地知道出了什么问题,以及您可以采取哪些措施来解决问题(如果需要修复)。

如果您想要更简洁的代码,但错误更准确,您还可以将这两项检查合并为一个guard

guard let buttonText = sender.titleLabel?.text, textAsInt = Int(buttonText) else {
    print("Something went wrong when converting the button title to an Int!")
    return
}

currentNumber = currentNumber*10 + Float(textAsInt)

如果您喜欢闭包,可以使用flatMap

guard let i = sender.titleLabel?.text.flatMap({Int($0)}) else {
    print("Something went wrong when converting the button title to an Int!")
    return
}

currentNumber = currentNumber*10 + Float(i)

flatMap选项起初看起来有点奇怪,但它所做的只是尝试转换按钮的titleLabel {{1}到text。如果失败,它将返回Intnil将拾取),否则它将返回文本的数值。

作为@vacawama said in the comments,您还可以使用nil合并运算符,以便在guard0titleLabel出现时使用text Int(...)

nil

但请记住,这可能会导致意外行为。我怀疑你的程序崩溃了,因为你的逻辑正在运行非数字按钮,例如" +"按钮。如果是这种情况,每次按非数字按钮时,您的数字都会乘以currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel?.text ?? "") ?? 0) 。您必须首先确保仅在数字按钮上调用您的逻辑。

虽然没有看到完整的代码,但很难确定。

有关如何安全处理选项的更多信息,请参阅此extensive Q&A on the subject