如何更改触发功能的顺序?
Posted
技术标签:
【中文标题】如何更改触发功能的顺序?【英文标题】:How can I change the order of functions triggered? 【发布时间】:2020-08-18 16:27:18 【问题描述】:我正在编写 Swift 编码,但我的代码中有问题。
在下面的代码中,我试图先获取表格视图单元格的信息,然后执行 segue。我也在使用 Firestore 来保存数据。问题是当我使用打印时,我可以先看到segue triggered!!!
,然后再看到document saved!!
。因为我想将doc.documentID
的值传递给下一个视图控制器,所以我想在触发执行segue之前保存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)
【问题讨论】:
【参考方案1】:数据是从 Firebase 异步加载的。由于这可能需要一些时间,因此您的完成处理程序的调用时间比您预期的要晚。
因此,任何需要数据库数据的代码都需要在完成处理程序中,或者从那里调用。
所以最简单的解决方法是将performSegue
移动到回调中:
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)
另见:
Is Firebase getDocument run line by line? Handling asynchronous Firestore data reading in tableView - ios Storing asynchronous Cloud Firestore query results in Swift,使用调度组来改变执行顺序。 How do I save data from cloud firestore to a variable in swift?【讨论】:
谢谢弗兰克。实际上,我已经尝试过了。在这种情况下,问题是 preformSegue 被触发了两次,我可以看到下一个视图控制器移动了两次......这很奇怪,因为我认为它在 querySnapshot!.documents 循环中的 for doc 之外,并且没有真正触发 segue.. . 啊,我看到您也缺少快照侦听器中的嵌套。我更新了我的答案以嵌套听众。但是您最好使用getDocument()
调用而不是addSnapshotListener
调用:firebase.google.com/docs/firestore/query-data/…
嗯。它仍然显示下一个视图控制器两次。在当前的视图控制器中,我也有准备功能,我看到有人说这可能是我两次获得 vc 的原因。但是即使我把prepare函数注释掉了,还是一样...
如果嵌套后还有两个回调,你试过getDocument()
吗?
好的。现在它起作用了。不再有 getDocument() 并且不得不使用 getDocuments,我认为这将是一个以上的文档,但在我的情况下似乎不是......非常感谢您的帮助!以上是关于如何更改触发功能的顺序?的主要内容,如果未能解决你的问题,请参考以下文章