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() }) }