Firebase删除观察员

在我的代码中移除Firebase观察者时遇到问题。 这里是结构的细分:

var ref = Firebase(url:"https://MY-APP.firebaseio.com/") var handle = UInt? override func viewDidLoad() { handle = ref.observeEventType(.ChildChanged, withBlock: { snapshot in //Do something with the data } } override func viewWillDisappear(animated: Bool) { if handle != nil { println("Removed the handle") ref.removeObserverWithHandle(handle!) } } 

现在,当我离开viewcontroller,我看到“删除句柄”打印,但是当我回到viewcontroller,我的观察员被调用两次为每个事件。 当我离开并再次回来时,它被称为三次。 等等为什么观察者不被移除?

我也在代码中稍后调用ref.setValue("some value") ,这可能与它有什么关系?

以为我有这个错误,但实际上我试图删除错误的参考观察员。

原始代码:

 let ref: FIRDatabaseReference = FIRDatabase.database().reference() var childAddedHandles: [String:FIRDatabaseHandle] = [:] func observeFeedbackForUser(userId: String) { if childAddedHandles[userId] == nil { // Check if observer already exists // NOTE: - Error is caused because I add .child(userId) to my reference and // do not when I call to remove the observer. childAddedHandles[userId] = ref.child(userId).observeEventType(.ChildAdded) { [weak self] (snapshot: FIRDataSnapshot) in if let post = snapshot.value as? [String:AnyObject], let likes = post["likes"] as? Int where likes > 0 { self?.receivedFeedback(snapshot.key, forUserId: userId) } } } } func stopObservingUser(userId: String) { // THIS DOES NOT WORK guard let cah = childAddedHandles.removeValueForKey(userId) else { print("Not observing user") return } // Error! I did not add .child(userId) to my reference ref.removeObserverWithHandle(cah) } 

固定代码:

 func stopObservingUser(userId: String) { // THIS WORKS guard let cah = childAddedHandles.removeValueForKey(userId) else { print("Not observing user") return } // Add .child(userId) here ref.child(userId).removeObserverWithHandle(cah) } 

鉴于这是2015年4月,错误仍然存​​在,我会为这个问题提出一个解决方法:

  • 保持对句柄的引用(比如说在一个字典中,并且在为同一事件types启动一个新的观察者之前,检查观察者是否已经在那里。

有处理周围有非常低的足迹(基于一些官方评论:)),所以它不会伤害那么多。

观察者必须在他们被放置的相同参考path上被移除。 并且发出的次数相同,或者对每个path使用ref.removeAllObserver()。

这是我使用的一个技巧,保持整洁:

 var fbObserverRefs = [FIRDatabaseReference]() // keep track of where observers defined. 

…然后,把观察者放在viewDidLoad()中:

 fbObserverRefs.append(ref.child("user/\(uid)")) fbObserverRefs.last!.observe(.value, with: { snap in // do the work... }) 

…然后,在viewWillDisappear()中,注意删除任何发布的观察者:

 // Only true when popped from the Nav Controller stack, ignoring pushes of // controllers on top. if isBeingDismissed || isMovingFromParentViewController { fbObserverRefs.forEach({ $0.removeAllObservers() }) }