我读了关于这个问题的其他堆栈溢出q& a但它似乎是一个tabBarController问题,我还没有发现任何问题。
我有一个带有3个标签的tabBarController。 tab1是我成功将信息发送到Firebase的地方。在tab2中,我有tableView,它成功地从tab1读取数据。
在tab2中,我的监听器位于viewWillAppear中。我在viewDidDisappear中删除了监听器(我也试过了viewWillDisappear),这里的某个地方就是问题所在。
export default class QueryController {
private datasets: Datasets = null;
constructor(datasets: Datasets) {
this.datasets = datasets;
}
一旦我从tab2切换到任何其他选项卡,第二个我回到tab2表数据加倍,然后如果我再次切换标签并返回三倍等我尝试在viewDidLoad中设置监听器,这会阻止表数据从我切换标签时复制,但是当我从tab1发送新信息时,信息永远不会在tab2中更新。
根据Firebase文档以及我在stackoverflow / google上阅读的其他内容,应该在viewWillAppear中设置侦听器并在viewDidDisappear中删除。
关于如何在标签之间切换时防止我的数据重复的任何想法?
TAB1
override func viewDidDisappear(animated: Bool) {
self.sneakersRef!.removeAllObservers()
//When I tried using a handle in viewWillAppear and then using the handle to remove the observer it didn't work here either
//sneakersRef!.removeObserverWithHandle(self.handle)
}
TAB2
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
class TabOneController: UIViewController{
var ref:FIRDatabaseReference!
@IBOutlet weak var sneakerNameTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.ref = FIRDatabase.database().reference()
}
@IBAction func sendButton(sender: UIButton) {
let dict = ["sneakerName":self.sneakerNameTextField.text!]
let usersRef = self.ref.child("users")
let sneakersRef = usersRef.child("sneakers").childByAutoID()
sneakersRef?.updateChildValues(dict, withCompletionBlock: {(error, user) in
if error != nil{
print("\n\(error?.localizedDescription)")
}
})
}
}
tab3什么都不做。我只是将它用作备用标签来与
来回切换答案 0 :(得分:2)
removeAllObservers
方法正常运行。您目前遇到的问题是由于细微遗漏:您永远不会清除 sneakerArray
的内容。
注意:事件回调中不需要dispatch_async
。 Firebase SDK在主队列上调用此函数。
答案 1 :(得分:1)
官方接受的答案由@vzsg发布。我只是为下一个遇到这个问题的人详细介绍它。投票给他答案。
当您使用.childAdded
时,基本上会发生什么,Firebase会循环并从节点(in my case the node is "sneakersRef"
)抓取每个孩子。 Firebase抓取数据,将其添加到数组(in my case self.sneakerArray
),然后返回以获取下一组数据,将其添加到数组等。通过在下一个循环开始时清除数组, FB完成后,数组将为空。如果你切换场景,你将总是有一个空数组,ui将显示的唯一数据是FB再次循环节点。
我也摆脱了dispatch_async调用,因为他说FB调用主队列中的函数。我只使用了self.tableView.reloadData()
在旁注中,您应该订阅firebase-community.slack.com。这是官方的Firebase闲置频道,这就是我发布这个问题的地方,vzsg回答了它。
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//CLEAR THE ARRAY DATA HERE before you make your Firebase query
self.sneakerArray.removeAll()
let usersRef = self.ref.child("users")
//Listener
self.sneakersRef = usersRef.child("sneakers")
//I tried using the handle
//---self.handle = self.sneakersRef!.observeEventType(.ChildAdded...
self.sneakersRef!.observeEventType(.ChildAdded, withBlock: {(snapshot) in
if let dict = snapshot.value as? [String:AnyObject]{
let sneakerName = dict["sneakerName"] as? String
self.sneakerArray.append(sneakerName)
//I didn't have to use the dispatch_async here
self.tableView.reloadData()
}
}), withCancelBlock: nil)
}
答案 2 :(得分:0)
感谢您提出这个问题。
我过去也遇到过同样的问题。我已经解决了这个问题,如下所示。
1)定义包含观察者列表的数组。
var aryObserver = Array<Firebase>()
2)添加观察者如下。
self.sneakersRef = usersRef.child("sneakers")
aryObserver.append( self.sneakersRef)
3)删除观察者,如下所示。
for fireBaseRef in self.aryObserver{
fireBaseRef.removeAllObservers()
}
self.aryObserver.removeAll() //Remove all object from array.