Я прочитал другое переполнение стека q & a об этой проблеме, но это проблема с tabBarController, в которой я ничего не нашел.Firebase removeAllObservers() продолжает делать вызовы при переключении просмотров -Swift2 iOS
У меня есть tabBarController с 3 вкладками. tab1 - это место, где я успешно отправляю информацию в Firebase. В tab2 у меня есть tableView, который успешно считывает данные из tab1.
В tab2 мой слушатель находится в видуWillAppear. Я удаляю слушателя в viewDidDisappear (я также пробовал viewWillDisappear), и где-то здесь возникает проблема.
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 на любую другую вкладку, то второй я возвращаюсь к TAB2 двойники таблиц данных, а затем, если я снова переключить вкладки и вернуться утраивает и т.д. Я попытался установить слушатель внутри viewDidLoad который предотвращает дублирование данных таблицы при переключении вкладок, но когда я отправляю новую информацию из tab1, информация никогда не обновляется в tab2.
В соответствии с документами Firebase и почти всем остальным, что я читал в stackoverflow/google, слушатель должен быть установлен в viewWillAppear и удален в viewDidDisappear.
Любые идеи о том, как предотвратить дублирование данных при каждом переключении между вкладками?
tab1
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)")
}
})
}
}
tab2
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
class TabTwoController: UITableViewController{
@IBOutlet weak var tableView: UITableView!
var handle: Uint!//If you read the comments I tried using this but nahhh didn't help
var ref: FIRDatabaseReference!
var sneakersRef: FIRDatabaseReference?
var sneakerArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.ref = FIRDatabase.database().reference()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
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)
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}
}), withCancelBlock: nil)
}
//I also tried viewWillDisappear
override func viewDidDisappear(animated: Bool) {
self.sneakersRef!.removeAllObservers()
//When I tried using the handle to remove the observer it didn't work either
//---sneakersRef!.removeObserverWithHandle(self.handle)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.sneakerArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("sneakerCell", forIndexPath: indexPath)
cell.textLabel?.text = sneakerArray[indexPath.row]
return cell
}
}
tab3 ничего не делает. Я просто использую его как альтернативную вкладку для переключения взад и вперед с помощью
Спасибо за помощь. Я удалил содержимое массива в viewDidDisappear после метода removeAllObserver(), например: self.sneakersRef! .removeAllObservers(), а затем self.sneakerArray.removeAll(). Он прекратил копировать. На самом деле я был очень стеснен в этом. Можете ли вы объяснить, почему мне нужно очистить массив? Из моего понимания каждый раз, когда представление загружается снова, содержимое в массиве одинаково. –
Когда вы начинаете подписку на узел Firebase, первое, что делает SDK, это загрузка текущего содержимого. С событиями '.childAdded' это означает, что вы получаете один обратный вызов для каждого ребенка; каждый раз, когда вы подписываетесь. Вы просто добавляете детей при каждом обратном вызове, что приводит к дублированию. – vzsg