【问题标题】:How to get around fatal unexpected nil error caused due to forced unwrapping [duplicate]如何解决由于强制展开导致的致命意外零错误[重复]
【发布时间】:2020-07-21 22:41:58
【问题描述】:

我刚刚开始学习 swift 的基础知识,并且正在使用 swiftui 制作一个计算器来掌握它的窍门。但是,在尝试强制解包变量时,我不断收到错误消息,即发现 nil 值。我知道使用强制展开不是安全的做法,所以我尝试用 if let 语句替换它,但那些只会让我的计算结果变为 0,即它永远不会进入 if let 语句。我的代码逻辑在图片中,任何帮助将不胜感激。

import SwiftUI

struct ContentView: View {
    @State private var firstnumber = 0
    @State private var secondnumber = 0
    @State private var operand = ""
    @State private var calctext = "0"
    @State private var isTyping = false

    var body: some View {
        ZStack { Color.black
            .edgesIgnoringSafeArea(.all)
            VStack(){
            TextField("0", text: $calctext)
                .padding(EdgeInsets(top: 150, leading: 20, bottom: 20, trailing: 20))
                .border(Color.gray, width: 2)
                .multilineTextAlignment(.trailing)
                .foregroundColor(Color.white)
                .font(.largeTitle)



            HStack{
                createbutton("AC")
                .buttonStyle(numberdesign1())
                Spacer()
                createbutton("+/-")
                .buttonStyle(numberdesign1())
                Spacer()
                createbutton(" % ")
                .buttonStyle(numberdesign1())
                Spacer()
                Button(action: {
                    self.operandclick("÷")
                }) {
                Text(" ÷ ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)
            }.padding()

            HStack{
                createbutton(" 9 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 8 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 7 ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.operandclick("×")
                }) {
                Text(" × ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)
            }.padding()

            HStack{
                createbutton(" 6 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 5 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 4 ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.operandclick("-")
                }) {
                Text(" - ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)
            }.padding()

            HStack{
                createbutton(" 3 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 2 ")
                .buttonStyle(numberdesign())
                Spacer()
                createbutton(" 1 ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.operandclick("+")
                }) {
                Text(" + ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)

            }.padding()

            HStack{
                Button(action: {
                    self.digitTapped("0")

                }) {
                    Text(" 0                           ")
                }
                .foregroundColor(Color.white)
                .padding(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
                .background(Color.gray)
                .border(Color.gray, width: 1)
                .cornerRadius(40.0)
                Spacer()
                createbutton("  .  ")
                .buttonStyle(numberdesign())
                Spacer()
                Button(action: {
                    self.calculate()
                }) {
                Text(" = ")
                }
                .buttonStyle(buttondesign())
                .cornerRadius(15.0)

            }.padding()



            }
            .aspectRatio(contentMode: .fill)

        }
    }

    private func createbutton(_ number: String) -> Button<Text> {
        return Button(action: {
            self.digitTapped(number)
        }) {
            (Text(number))
        }
    }

    private func digitTapped(_ number: String) -> Void {
        if isTyping {
            calctext += number
        } else {
            calctext = number
            isTyping = true
        }
    }

    private func operandclick(_ operand: String) {
        isTyping = false
//        if Int(calctext) != nil {
        firstnumber = Int(calctext)!
//        }
        
        self.operand = operand
        calctext = operand
    }

    private func calculate() {
        isTyping = false
        var result = 0
//        if Int(calctext) != nil {
        secondnumber = Int(calctext)!
//        }
        

        if operand == "+" {
            result = firstnumber + secondnumber
            print (result, firstnumber, secondnumber)
        } else if operand == "-" {
            result = firstnumber - secondnumber
        } else if operand == "÷" {
            result = firstnumber / secondnumber
        } else if operand == "×" {
            result = firstnumber * secondnumber
        }

        calctext = "\(result)"
    }
}




struct buttondesign: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(Color.white)
            .padding()
            .background(LinearGradient(gradient: Gradient(colors: [Color("DarkGreen"),Color("LightGreen")]), startPoint: .leading, endPoint: .trailing))
        .clipShape(Circle())
    }
}

struct numberdesign: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
        .foregroundColor(Color.white)
            .padding(.all)
        .background(Color.gray)
        .border(Color.gray, width: 1)
            .clipShape(Circle().scale(1))

    }
}

struct numberdesign1: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
        .foregroundColor(Color.black)
        .padding(.all)
        .background(Color("LightGray"))
        .border(Color.gray, width: 1)
        .clipShape(Circle())

    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }

}

【问题讨论】:

  • 崩溃时calctext 中的内容是什么?
  • 您应该发布代码本身而不是代码图片。这允许人们通过将代码粘贴到项目或 Playground 中来试用您的代码,并允许代码显示在 StackOverflow 上的搜索中。
  • 顺便说一句:运算符是执行操作的“函数”,而操作数是该函数的输入。在表达式 3 + 4 = 7 中,运算符是 '+' - 因为它告诉我们如何执行操作 - 操作数是 3 和 4 - 操作所依据的输入。
  • 嗨,calctext 在崩溃时包含 nil,原因我无法理解。我尝试在原始帖子上发布我的代码,但它一直给我格式错误。我现在将使用代码本身更新我的帖子,并感谢您的提示!我没有注意到我命名了错误的操作数。
  • 不能为nil,它是一个String。当它崩溃时,在调试器中打印 calctext 的值。

标签: swift swiftui


【解决方案1】:

确保您的 String 没有空间,因为它无法将其转换为整数并且将返回 nil,如果您强制 Cast 它将 crash

【讨论】:

    【解决方案2】:

    除非你确定它们不包含任何 nil 值,否则你不应该强制解包选项。

    我建议您使用nil coalescing 运算符为字符串的整数转换提供默认值

    let firstNumber = Int(calcText) ?? 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      相关资源
      最近更新 更多