我在代码中删除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时,我看到“Removed the handle”被打印出来,但是当我返回viewcontroller时,我的观察者会为每个事件调用两次。当我离开并再次返回时,它被召唤三次。等等。为什么观察者没有被移除?
我稍后也会在代码中调用ref.setValue("some value")
,这与它有什么关系吗?
答案 0 :(得分:2)
以为我遇到了这个错误,但实际上我试图在错误的引用上删除观察者。
原始代码:
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)
}
答案 1 :(得分:1)
鉴于它已经到了2015年4月,而且问题仍然存在,我建议解决这个问题:
周围的手柄占用空间非常小(基于一些官方评论:))所以它不会受到太大伤害。
答案 2 :(得分:0)
观察者必须在他们所使用的相同参考路径上删除。并且发布的次数相同,或者为每个路径使用ref.removeAllObservers()。
这是我使用的一个技巧,以保持整洁:
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() })
}