Swift 如何更改已触发函数的顺序?

Swift 如何更改已触发函数的顺序?,swift,google-cloud-firestore,syntax,segue,Swift,Google Cloud Firestore,Syntax,Segue,我正在进行Swift编码,我的代码中有问题。 在下面的代码中,我试图首先获取表视图单元格的信息,然后执行segue。我还使用Firestore保存数据。问题是当我使用print时,我可以看到segue被触发先保存,然后保存文档。由于我想将doc.documentID的值传递给下一个视图控制器,所以我想在触发执行序列之前保存documentID class HomeViewController: UIViewController { var gameDocumentID = "&

我正在进行Swift编码,我的代码中有问题。 在下面的代码中,我试图首先获取表视图单元格的信息,然后执行segue。我还使用Firestore保存数据。问题是当我使用print时,我可以看到
segue被触发先保存,然后
保存文档。由于我想将
doc.documentID
的值传递给下一个视图控制器,所以我想在触发执行序列之前保存documentID

class HomeViewController: UIViewController {
    var gameDocumentID = ""
// more codes here...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == K.homeToGameScreen {
            let gameScreenVC = segue.destination as! GameScreenViewController

                gameScreenVC.gameDocumentID = gameDocumentID
        }
    }
}


        extension HomeViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // serch game db where player1 is ready to play
    
    db.collection(K.FStore.newGameCpllection).whereField(K.FStore.uID, isEqualTo: players[indexPath.row].uID).addSnapshotListener { (querySnapshot, err) in
        if let err = err {
            print("Error getting game db: \(err)")
        } else {
            
            for doc in querySnapshot!.documents {
                
                print("document saved!!")
                self.gameDocumentID = doc.documentID
            
            self.db.collection(K.FStore.newGameCpllection).document(self.gameDocumentID).updateData([
                K.FStore.player2Field: self.playerInfo[K.FStore.nameField]!
            ]) { err in
                if let err = err {
                    print("Error updating document: \(err)")
                } else {
                    print("Document successfully updated")
                    
                }
                print("segue triggered!!!")
                self.performSegue(withIdentifier: K.homeToGameScreen, sender: self)
                }
            }
            }
        
        }

    }
}

数据从Firebase异步加载。因为这可能需要一些时间,所以调用完成处理程序的时间比您预期的要晚

因此,任何需要数据库数据的代码都需要在完成处理程序中,或者从那里调用

因此,最简单的修复方法是将
performsgue
移动到回调中:

extension HomeViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    db.collection(K.FStore.newGameCpllection)
      .whereField(K.FStore.uID, isEqualTo:players[indexPath.row].uID)
      .addSnapshotListener { (querySnapshot, err) in
            if let err = err {
                print("Error getting game db: \(err)")
            } else {
                for doc in querySnapshot!.documents {
            
                print("document saved!!")
                self.gameDocumentID = doc.documentID                
                self.db.collection(K.FStore.newGameCpllection).document(self.gameDocumentID).updateData([
                    K.FStore.player2Field: self.playerInfo[K.FStore.nameField]!
                ]) { err in
                    if let err = err {
                        print("Error updating document: \(err)")
                    } else {
                        print("Document successfully updated")
                    }
                    print("segue triggered!!!")
                    self.performSegue(withIdentifier: K.homeToGameScreen, sender: self)
                }
            }
            
        }
    }
    }
}
另见:

  • ,使用调度组似乎可以更改执行顺序

谢谢你,弗兰克。事实上,我已经试过了。在这种情况下,问题是preformSegue被触发两次,我可以看到下一个视图控制器移动两次。。。这很奇怪,因为我觉得这超出了《querySnapshot》中医生的范围!。文档循环,没有任何东西真正触发segue…啊,我看到快照侦听器中也缺少嵌套。我会更新我的答案,以嵌套听众。但是您最好使用
getDocument()
调用,而不是
addSnapshotListener
calls:hmmmm。仍然会显示两次“下一个视图控制器”。在当前的视图控制器中,我还具有prepare功能,我看到一些人说这可能是我两次获得vc的原因。但即使我注释掉了prepare函数,它仍然是一样的……如果嵌套后仍有两个回调,是否尝试了
getDocument()
?确定。现在它起作用了。不再有getDocument()了,必须使用getDocuments,我认为它将是多个文档,但在我的情况下似乎不是这样。。。非常感谢你的帮助!