空数组导致我的应用程序在Swift中崩溃

时间:2017-06-29 00:27:33

标签: ios arrays swift

我一直遇到这个错误“致命错误:索引超出范围”,经过研究,我仍然不确定如何解决这个问题。为了给出上下文,我开始使用空数组var playersArray = [UITextField](),以便用户可以输入他们的名字来玩游戏。然后,我确保用户在每个名称空间的文本字段中输入或未输入值

if let player1Name = name1.text, !player1Name.isEmpty
        {   playersArray.append(name1)

        } else {
            print("Player 1 Empty")

如果玩家在该文本字段中输入了值,则将该值附加到数组中。 我遇到的问题是,如果我运行游戏并且没有用户在10个文本字段中输入任何名称,则游戏将崩溃。我假设这是因为数组是空的?

错误出现在这一行,我将用于游戏的名称随机化为数组中的元素数量:

 let RandomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]

我假设如果数组为空,那么.count将不起作用?

如果阵列为空,我怎样才能确保游戏不会崩溃?

CODE:

 var playersArray = [UITextField]()

    override func viewDidLoad() {
        super.viewDidLoad()
        textColor()
        question1View.isHidden = true
        questionLabel.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2)


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // Alert message on startup
    func alertMessageOnStartUp(){
        let alert = UIAlertController(title: "Warning!", message: "Please drink responsibly. By continuing, you agree that you are responsible for any consequences that may result from BottomsUp.", preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Agree", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }

    // Dismiss keyboard when tapped outside the keyboard
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

    // Dimiss keybaord when return button is tapped
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        name1.resignFirstResponder()
        name2.resignFirstResponder()
        name3.resignFirstResponder()
        name4.resignFirstResponder()
        name5.resignFirstResponder()
        name6.resignFirstResponder()
        name7.resignFirstResponder()
        name8.resignFirstResponder()
        name9.resignFirstResponder()
        name10.resignFirstResponder()
        return(true)
    }

    //randomise background colour of each question page
    func getRandomBackgroundColor() -> UIColor{
        let randomRed:CGFloat = CGFloat(drand48())
        let randomGreen:CGFloat = CGFloat(drand48())
        let randomBlue:CGFloat = CGFloat(drand48())
        return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0)
    }

        func textColor(){
        name1.textColor = UIColor.white
        name2.textColor = UIColor.white
        name3.textColor = UIColor.white
        name4.textColor = UIColor.white
        name5.textColor = UIColor.white
        name6.textColor = UIColor.white
        name7.textColor = UIColor.white
        name8.textColor = UIColor.white
        name9.textColor = UIColor.white
        name10.textColor = UIColor.white
    }

    @IBAction func playButton(_ sender: Any) {
        alertMessageOnStartUp()

        if let player1Name = name1.text, !player1Name.isEmpty
        {   playersArray.append(name1)

        } else {
            print("Player 1 Empty")
        }

        if let player2Name = name2.text, !player2Name.isEmpty
        {   playersArray.append(name2)

        } else {
            print("Player 2 Empty")
        }

        if let player3Name = name3.text, !player3Name.isEmpty
        {   playersArray.append(name3)

        } else {
            print("Player 3 Empty")
        }

        if let player4Name = name4.text, !player4Name.isEmpty
        {   playersArray.append(name4)

        } else {
            print("Player 4 Empty")
        }

        if let player5Name = name5.text, !player5Name.isEmpty
        {   playersArray.append(name5)

        } else {
            print("Player 5 Empty")
        }

        if let player6Name = name6.text, !player6Name.isEmpty
        {   playersArray.append(name6)

        } else {
            print("Player 6 Empty")
        }

        if let player7Name = name7.text, !player7Name.isEmpty
        {   playersArray.append(name7)

        } else {
            print("Player 7 Empty")
        }

        if let player8Name = name8.text, !player8Name.isEmpty
        {   playersArray.append(name8)

        } else {
            print("Player 8 Empty")
        }

        if let player9Name = name9.text, !player9Name.isEmpty
        {   playersArray.append(name9)

        } else {
            print("Player 9 Empty")
        }

        if let player10Name = name10.text, !player10Name.isEmpty
        {   playersArray.append(name10)

        } else {
            print("Player 10 Empty")
        }

        question1View.isHidden = false
        question1View.backgroundColor = getRandomBackgroundColor()


        let RandomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]
        let RandomQuestion = questionArray[Int(arc4random_uniform(UInt32(questionArray.count)))]
        questionLabel.text = RandomPlayer.text! + RandomQuestion

    }

    @IBAction func nextQuestionButton(_ sender: Any) {
        question1View.backgroundColor = getRandomBackgroundColor()

        let RandomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]
        let RandomQuestion = questionArray[Int(arc4random_uniform(UInt32(questionArray.count)))]
        questionLabel.text = RandomPlayer.text! + RandomQuestion
    }
}

2 个答案:

答案 0 :(得分:1)

打破这个局面:

Int(arc4random_uniform(UInt32(playersArray.count)))

此行获取一个随机数,最小值为0,且playerArray长度的最大值减去1。

我实际上不确定当你传入的论点是0时它做了什么,但它并不重要,正如我们接下来会看到的那样。

然后你在这里使用那个随机值:

playersArray[thatRandomNumber]

因为playersArray中没有元素,无论thatRandomNumber的值是什么,它都会超出范围。

你可能想要更像这样的东西:

let RandomPlayer = <some default value>
if !playersArray.isEmpty {
    RandomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]
}

修改

您的最新代码似乎无法阻止索引到空数组。

你有:

@IBAction func playButton(_ sender: Any) {
    ...
    let RandomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]
    let RandomQuestion = questionArray[Int(arc4random_uniform(UInt32(questionArray.count)))]
    questionLabel.text = RandomPlayer.text! + RandomQuestion
}

你需要:

@IBAction func playButton(_ sender: Any) {
    ...
    if playersArray.isEmpty {
         // do something about that
    } else {
        let RandomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]
        let RandomQuestion = questionArray[Int(arc4random_uniform(UInt32(questionArray.count)))]
        questionLabel.text = RandomPlayer.text! + RandomQuestion
    }
}

答案 1 :(得分:0)

一个空数组的playersArray.count是0,所以你试图访问playersArray [0] - 但数组是空的,所以0索引不存在任何内容。

你应该这样做:

let randomPlayer: Player
if !playersArray.isEmpty {
   randomPlayer = playersArray[Int(arc4random_uniform(UInt32(playersArray.count)))]
} else {
   randomPlayer = Player() //create a fallback player
}

或者,您可以将randomPlayer设为可选项,而不是提供后备值。取决于您对该变量的需求。