Ios UITableView:IndexPath.row超出范围(致命错误)

Ios UITableView:IndexPath.row超出范围(致命错误),ios,swift,uitableview,Ios,Swift,Uitableview,我有一个表格视图,列出了与游戏相关的人员。当玩家被淘汰时,我运行以下代码: func doRemovePlayer(playerDed: GKPlayer) { print("\n ** Removing \(playerDed.alias!) from the game! ** \n") gameLog += "Removing \(playerDed.alias!) from the game!" let elIndex = (gKPlayerArray.index

我有一个表格视图,列出了与游戏相关的人员。当玩家被淘汰时,我运行以下代码:

func doRemovePlayer(playerDed: GKPlayer) {

    print("\n ** Removing \(playerDed.alias!) from the game! ** \n")
    gameLog += "Removing \(playerDed.alias!) from the game!"
    let elIndex = (gKPlayerArray.index(of: playerDed))!
    scoreArray.remove(at: elIndex)
    randomNoArray.remove(at: elIndex)
    timeResultsArray.remove(at: elIndex)
    answerResultArray.remove(at: elIndex)
    playersReadyForNextStage.remove(at: elIndex)
    gKPlayerArray.remove(at: elIndex)
    noOfPlayers -= 1
    print ("New Array counts are: \(scoreArray.count), \(randomNoArray.count), \(timeResultsArray.count), \(answerResultArray.count), \(playersReadyForNextStage.count), \(gKPlayerArray.count), Players: \(noOfPlayers)")
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.01, execute: {
        self.scoreBoardTable.reloadData()
    })
    checkIfWinnerOrLoser()
}
正如您所看到的,我使用调度队列只是为了避免任何问题(我想)。 无论如何,当我在2个模拟器和我的实际iPhone上运行此代码时,模拟器对此代码没有问题,但是iPhone 3/4次给了我一个致命错误:索引超出范围,并指向代码中的这一行:

extension GameScreenVC: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return gKPlayerArray.count
    }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let scoreCell = tableView.dequeueReusableCell(withIdentifier: "playerCell") as! ScoreBoardTableCell
    **scoreCell.nameLabel.text = gKPlayerArray[indexPath.row].alias!** //FATAL ERROR: INDEX OUT OF RANGE
    scoreCell.scoreLabel.text = String(scoreArray[indexPath.row])
    if indexPath.row == 0 {
        scoreCell.layer.borderWidth = 3
        scoreCell.layer.borderColor = UIColor.blue.cgColor
    } else {
        scoreCell.layer.borderWidth = 0
    }
    scoreCell.statusLabel.layer.cornerRadius = 7
    if playersReadyForNextStage[indexPath.row] {
        scoreCell.statusLabel.layer.backgroundColor = UIColor.yellow.cgColor
    } else {
        scoreCell.statusLabel.layer.backgroundColor = UIColor.green.cgColor
    }
    return scoreCell
}
我不知道如何解决这个问题。我会“打印”所有数组的新值以防万一,并确认它们都是正确的(它们是3,现在是2)。然后,当它运行表的更新时,它会崩溃,以为indexPath.row中有第三个元素?(我想这就是正在发生的事情)。
IndexPath.row是否像未更新或其他什么?有没有办法更正确地更新它?

如果在主线程上调用了
doRemovePlayer
,您就没有理由在以后调度reload。试着简单地说:

func doRemovePlayer(playerDed: GKPlayer) {

    print("\n ** Removing \(playerDed.alias!) from the game! ** \n")
    gameLog += "Removing \(playerDed.alias!) from the game!"
    let elIndex = (gKPlayerArray.index(of: playerDed))!
    scoreArray.remove(at: elIndex)
    randomNoArray.remove(at: elIndex)
    timeResultsArray.remove(at: elIndex)
    answerResultArray.remove(at: elIndex)
    playersReadyForNextStage.remove(at: elIndex)
    gKPlayerArray.remove(at: elIndex)
    noOfPlayers -= 1
    print ("New Array counts are: \(scoreArray.count), \(randomNoArray.count), \(timeResultsArray.count), \(answerResultArray.count), \(playersReadyForNextStage.count), \(gKPlayerArray.count), Players: \(noOfPlayers)")
    // it should be enough to delete the corresponding row
    scoreBoardTable.deleteRows(at: [IndexPath(row: elIndex, section: 0)], with: .automatic)
    checkIfWinnerOrLoser()
}

你能发布你的
numberOfRow
方法吗?哦!!是的,对不起。我打印了gKPlayerArray.count,这是正确的。除了调用
重新加载数据
,iPhone崩溃的刷新可能是由其他调用启动的吗?我认为RemovePlayer不在主线程中。我执行了
调度queue.main.async{gkplayerary.remove(at:elIndex)}
(因为它是负责设置行数的数组)。它现在似乎正在工作(到目前为止3/3没有崩溃)@dvd.Void你认为呢?伙计,密码是准确的,你也必须准确。。调用的
doRemovePlayer
在哪里?您可以使用
print(“在主线程上:”,thread.isMainThread)
…好的,我测试了它。它在主线程上运行。那么我应该删除所有的调度队列吗?(但是请注意,过去我没有它们,我有崩溃。现在我添加了它们,没有崩溃)@dvd.Void当然。。如果没有必要,用分派调用来混乱代码是没有意义的。。你应该没事的我们只要我的密码。。除非还有其他问题