Swift 如何分离本地作用域中的侦听器?

Swift 如何分离本地作用域中的侦听器?,swift,google-cloud-platform,google-cloud-firestore,listener,observers,Swift,Google Cloud Platform,Google Cloud Firestore,Listener,Observers,我想在按下按钮时分离viewController中的snapshotListener。我正在阅读其他堆栈溢出问题和文档,他们在同一个函数中为侦听器调用remove方法。在我的情况下,我试着这么做,但我的快照监听器根本没有工作 这是我想要调整的函数和代码块 @objc func doneTapped() { let updateListener = db.collection("school_users/\(user?.uid)/events").whereF

我想在按下按钮时分离viewController中的
snapshotListener
。我正在阅读其他堆栈溢出问题和文档,他们在同一个函数中为侦听器调用remove方法。在我的情况下,我试着这么做,但我的快照监听器根本没有工作

这是我想要调整的函数和代码块

@objc func doneTapped() {
    
    let updateListener = db.collection("school_users/\(user?.uid)/events").whereField("event_name", isEqualTo: navigationItem.title).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
        if let error = error {
            print("There was an error fetching the documents: \(error)")
        } else {
            self.eventName = querySnapshot!.documents.map { document in
                return EventName(eventName: (document.get("event_name") as! String))
            }
            
            self.db.document("school_users/\(self.user?.uid)/events/\(self.docIDUneditableTextF.text!)").updateData(["event_date": self.dateEditableTextF.text, "event_cost": self.costEditableTextF.text, "for_grades": self.gradesEditableTextF.text]) { (error) in
                if let error = error {
                    print("There was an error updating the document: \(error)")
                } else {
                   print("The document was successfully updated."
                }
            }
        }
    }
    
    dateEditableTextF.resignFirstResponder()
    dateEditableTextF.isEnabled = false
    
    costEditableTextF.resignFirstResponder()
    costEditableTextF.isEnabled = false
    
    
    gradesEditableTextF.resignFirstResponder()
    gradesEditableTextF.isEnabled = false
    
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))

}

我尝试调用updateListener.remove(),但它使我的snapshotListener根本无法工作,而且当文档更新时,打印语句永远不会结束,这也是因为侦听器仍然处于活动状态还是另一个问题?

addSnapshotListener
会在数据更改时为您提供更新。我不清楚,如果你真的想接收更新,为什么要立即删除侦听器——正如你所指出的,立即删除它基本上会导致它根本无法工作。也许可以发布一个链接,链接到一些您看到了所引用代码的帖子/文档,有人可以深入了解正在发生的事情

我怀疑你实际上并不需要数据的更新。在这种情况下,您只需使用
.getDocuments()
。有关获取数据的不同方法,请参见此处的Firestore文档:

第二个问题(无限打印)与第一个有关。因为您有一个监听器,当数据更改时,它将返回更新,当您进行第二次数据库调用时(您的
updateData
),它将更新您的数据,再次触发监听器。这将继续循环,因为他们将继续互相呼叫。这是另一个迹象,表明您实际上并不需要侦听器,而是需要一个调用来获取数据。如果您确实想要更新,那么您必须找到一种方法来分离第二个请求,这样您就不会进入循环

基于评论更新:(/strong>在不同函数中删除侦听器的示例)

在视图、视图控制器等上,为侦听器声明一个属性:

class MyViewController : UIViewController {
  private var documentListener: ListenerRegistration? //assuming that ListenerRegistration is the correct type here, but you can check the current type of your updateListener to check
}
然后,在函数中,将侦听器设置为:

documentListener = db.collection("school_users/\(user?.uid)/events").whereField("event_name", isEqualTo: navigationItem.title).addSnapshotListener()...
然后,稍后(如在
视图中)可以将其删除:

documentListener?.remove()

我不想立即删除该侦听器我只是想找出一种方法来阻止它,因为该侦听器不会停止,结果在30分钟内超过了每日限制。另外,你必须解释解耦,我不知道你的第二个请求是什么意思。我当然想要更新,因为实时快照侦听器在应用程序中扮演着重要角色。如果你能解释一下解耦或者把我引向一个来源,那将是非常感谢的。我看到的文档的链接@JNPDX您刚才发送的链接并不一定表明在同一个函数中调用了remove()-它只是向您展示了如何删除它是的,我知道,我想知道如何在不同的函数中删除侦听器调用,例如viewdiddecouple()或类似@jnpdxBy decouple的东西,我的意思是,您不能在对快照侦听器的回调中调用updateData(),因为它最终将调用一个无限循环,就像您已经经历过的和我描述过的那样。我不知道有什么来源可以链接到你,尽管你可以通过谷歌“递归循环”来了解更多。如何处理这个问题的决定是一个架构性的决定。我将更新我的答案,以反映在不同的函数中删除侦听器。。。一秒钟。