首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Firebase删除观察者

Firebase删除观察者
EN

Stack Overflow用户
提问于 2014-11-25 18:23:31
回答 3查看 4.4K关注 0票数 8

我在删除代码中的Firebase观察者时遇到问题。以下是该结构的详细信息:

代码语言:javascript
复制
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!)
    }
}

现在,当我离开视图控制器时,我看到打印了“删除句柄”,但是当我返回到视图控制器时,我的观察器被调用了两次。当我离开并再次返回时,它会被调用三次。等。为什么观察者没有被移除?

我在后面的代码中也调用了ref.setValue("some value"),这与它有什么关系吗?

EN

回答 3

Stack Overflow用户

发布于 2016-06-25 07:19:55

我认为我有这个bug,但实际上我试图删除错误引用上的观察者。

原始代码:

代码语言:javascript
复制
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)
}

修复代码:

代码语言:javascript
复制
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)
}
票数 2
EN

Stack Overflow用户

发布于 2015-04-16 04:33:37

考虑到现在是2015年4月,bug仍然存在,我会提出一个解决问题的方法:

  • 保留句柄的引用(假设在字典中,在启动相同事件类型的新观察者之前,检查观察者是否已经存在。

拥有手柄的占用空间非常小(基于一些官方评论:),所以它不会有太大的伤害。

票数 1
EN

Stack Overflow用户

发布于 2017-03-21 06:33:06

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

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

代码语言:javascript
复制
var fbObserverRefs = [FIRDatabaseReference]()    // keep track of where observers defined.

...then,将观察者放在viewDidLoad()中:

代码语言:javascript
复制
fbObserverRefs.append(ref.child("user/\(uid)"))
fbObserverRefs.last!.observe(.value, with: { snap in
    // do the work...
})

在viewWillDisappear()中,...then负责删除任何已发出的观察者:

代码语言:javascript
复制
// Only true when popped from the Nav Controller stack, ignoring pushes of 
// controllers on top.
if isBeingDismissed || isMovingFromParentViewController {
    fbObserverRefs.forEach({ $0.removeAllObservers() })
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27124118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档