我试图听从建议并在需要时删除监听器并在需要时注册监听器。所以在我的 UIViewController.viewDidAppear 中我有以下内容:
let chatRef = messagesRef.childByAppendingPath(chat.objectId!)
var query = chatRef.queryOrderedByChild("createdAt")
if let since = since {
query = query.queryStartingAtValue(since.timeIntervalSince1970 * 1000)
}
let handle = query.observeEventType(FEventType.ChildAdded, withBlock: completion, withCancelBlock: { (error: NSError!) -> Void in
println("error listening for new Chat messages: \(error)")
});
在我的 UIViewController.viewWillDisappear() 中有
let chatRef = messagesRef.childByAppendingPath(chat.objectId!)
if chatRef != nil {
chatRef.removeAllObservers()
}
但是每次第二次进入 ViewController 时程序都会崩溃(转到 View Controller ,导航离开,然后返回)并出现以下错误:
*** Assertion failure in -[FPersistentConnection listen:tagId:hashFn:onComplete:], /Users/mtse/Dev/firebase/firebase-client-objc/Firebase/Firebase/Core/FPersistentConnection.m:127
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'listen() called twice for the same query'
如果我不移除观察者并且只在 viewDidLoad
而不是 viewDidAppear 中调用一次 observeEventType,程序运行良好。
即使我删除了观察者然后如果我不执行 queryOrderedByChild
和 queryStartingAtValue
将其添加回来,程序也能正常运行。
那么我做错了什么?
最佳答案
免责声明:我为 Firebase 工作
Firebase 中的监听器特定于您注册它们的路径或查询。调用 removeAllObservers()
会移除所有观察者,但仅从该路径移除。
因此,在您的 viewWillDisappear()
中,您需要从查询中移除监听器,而不是从引用中移除。
query.removeAllObservers()
我们刚刚在文档中更明确地说明了这一点,并且正在寻找使 API 更直观的方法。
更新 (20150724)
事实证明,在 FFirebase
上调用 removeAllObservers()
也应该删除同一位置上查询的所有观察者。它不会删除 child()
位置的观察者,但应该适用于您的情况。
我们正在调查问题出在哪里,但您似乎遇到了我们 iOS SDK 中的错误。一旦我们找到它,我们将发布一个固定版本。同时,以上内容作为(并将继续作为)有效的解决方法。
关于ios - Firebase 崩溃并出现 'listen() called twice for the same query' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31599541/