使用Firebase,Swift removeObserver(withHandle不会删除观察者

时间:2017-04-26 12:57:46

标签: swift firebase firebase-realtime-database

使用removeObserver(在Swift 3中使用withHandle,在viewDidDisappear上不删除Observer

var query = FIRDatabaseQuery()

var postRef: FIRDatabaseReference!
var postRefHandle: FIRDatabaseHandle?

override func viewDidLoad() {
    super.viewDidLoad()

    postRef = baseRef.child("Posts")
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    if postRefHandle != nil {
        //try 1:
        //postRef.removeObserver(withHandle: postRefHandle!)

        //try 2:
        //postRef.queryOrdered(byChild: "sortTimestamp").removeObserver(withHandle: postRefHandle!)

        //try 3: 
        //query.removeObserver(withHandle: postRefHandle!)
    }
    //try 4:
    //postRef.removeAllObservers() //works
}

func getPosts()
{
    var count = 20 

    query = postRef.queryOrdered(byChild: "sortTimestamp")

    postRefHandle = query.queryLimited(toFirst: UInt(count)).observe(.childAdded //etc.
}

所以我尝试了viewDidDisappear中的三个方法,但是没有删除观察者。 尝试3 query.removeObserver(withHandle:postRefHandle!),作为Firebase, how do I return a handle so that I can call removeObserver?的答案,由frank-van-puffelen

唯一有效的是try 4中概述的那个。 我无法用removeObserver删除Observer的任何原因(withHandle?(try 1 - 3)

另外“query.queryLimited(toFirst:UInt(count))。观察(.childAdded”没有从Firebase获取最新数据。我认为观察总是得到更新的数据,而不是observeSingleEvent。为什么不这样做吗?

非常感谢任何建议。

3 个答案:

答案 0 :(得分:9)

如果您有以下代码:

var postsRef: FIRDatabaseReference!
var postRefHandle: FIRDatabaseHandle!
var query = FIRDatabaseQuery()

func addHandler() {

    self.postsRef = self.ref.child("posts")
    var count = 20
    self.query = self.postsRef.queryOrdered(byChild: "sortTimestamp")

    self.postRefHandle = self.query.queryLimited(toFirst: UInt(count)).observe(.childAdded, with: { snapshot in
        print(snapshot) 
    })
}

以后再执行此功能

self.postsRef.removeObserver(withHandle: self.postRefHandle!)

它删除了观察者。这是经过测试的代码。

对于问题的第二部分:querySingleEvent和observe在数据方面做同样的事情,但有不同的行为。它们都将始终获得当前数据 - 由startAt,endAt,equalTo等修改

  

observeSingleEvent返回数据,不会让观察者离开   如果数据发生变化,我们将不会收到通知

     

observe返回数据并使观察者附加到节点   并将通知您未来的变化。

.childAdded:将任何子节点添加到节点时 .childChanges:当任何孩子在节点中发生变化时 .childRemoved:当孩子被移除时。

答案 1 :(得分:1)

我如何能够做到这一点是通过删除子参考。

var recentRef: FIRDatabaseReference!

recentRef.child("\(groupId)").observe(.value, with: { (snapshot) in

                    recentRef.removeAllObservers() // not_working
                    recentRef.child("\(groupId)").removeAllObservers() //working

                    if let obj = snapshot.value as? [String: AnyObject] {
                            //... code here
                    }
                })

答案 2 :(得分:1)

您也可以不进行查询就实现此目的(快速4)- 这样可以正确删除观察者的参考并为我工作。

   private let ref = Database.database().reference().child("classTalks")
   private var refHandle: DatabaseHandle!

    override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear()
     talkRefHandle = talkRef.observe(.value, with: { (snapshot) in
            })
    }

        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear()
            talkRef.removeObserver(withHandle: talkRefHandle)

    }