2017-06-29 32 views
-1

我經常遇到這個錯誤「致命錯誤:索引超出範圍」,經過研究後,我仍然不確定如何解決這個問題。爲了給出上下文,我已經開始使用空數組var playersArray = [UITextField](),以便用戶可以輸入他們的名字來玩遊戲。然後我要確保用戶擁有或如果玩家已經進入了一個值到該文本框,然後生病追加該值數組還沒有進入一個值的文本字段每個名稱插槽空陣列導致我的應用程序在Swift崩潰

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 
    } 
} 

回答

1

打破下來:

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

這條線得到一個隨機數爲0的最小值和playersArray的長度減去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 
    } 
} 
+0

我可以使用靜態值而不是計數嗎?因爲最大用戶數將是10? –

+0

你的意思是恆定的價值嗎?不,因爲如果只有5名球員,你不想從0到9挑選一個隨機數,你想從0到4中選一個。 – smarx

+0

當你有1到10名球員時它很好,它只有在那裏是0名球員。默認值是多少? –

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可選的,而不是提供一個備用的值。取決於您對該變量的需求。

+0

我想它,如果數組爲空,提示用戶添加一個球員的名字 –

+0

你可以把你在想要的任何行爲else語句 – BJHStudios