所以我对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)
答案 0 :(得分:3)
如评论中所述,您应该始终避免使用'崩溃运算符' (!
) - 并学会安全地处理可选值。
您的程序崩溃了,因为titleLabel
,text
或Int(...)
都是nil
- 然后您正试图强行打开它们。这可能意味着您的按钮没有titleLabel
或titleLabel
的文字无法转换为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
。如果失败,它将返回Int
(nil
将拾取),否则它将返回文本的数值。
作为@vacawama said in the comments,您还可以使用nil合并运算符,以便在guard
,0
或titleLabel
出现时使用text
Int(...)
:
nil
但请记住,这可能会导致意外行为。我怀疑你的程序崩溃了,因为你的逻辑正在运行非数字按钮,例如" +"按钮。如果是这种情况,每次按非数字按钮时,您的数字都会乘以currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel?.text ?? "") ?? 0)
。您必须首先确保仅在数字按钮上调用您的逻辑。
虽然没有看到完整的代码,但很难确定。
有关如何安全处理选项的更多信息,请参阅此extensive Q&A on the subject。