Intereting Posts
Как показать MKAnnotationView в центре MKPolygon во время увеличения / уменьшения? Приложение Calendar хочет синхронизировать с календарем ios в быстром Двоичный оператор '/' не может применяться к двум операндам «UInt32» Как использовать hidesBottomBarWhenPushed, если я хочу скрыть вкладку только для одного типа контроллера? Проблемы при отправке электронной почты через разницу в телефоне iOS Утечка памяти при использовании функции performSelectorInBackground Как я могу показать свое приложение в меню, которое отображается, когда текст выбран в другом приложении iOS? ReplayKit и название предварительного просмотра всплывающее диалоговое окно Сохранение устройстваУказание NSUserDefaults Тип «NSFastEnumerationIterator.Element» (aka «Any») не имеет элементов подстроки изменение цвета тени на UIBezierPath Уменьшение размера приложения iOS для AppStore (Xamarin) Могу ли я регулировать использование процессора NSOperation / Thread на iOS? Быстрая регистрация с использованием учетных данных Active Directory / аутентификации

Firebase removeAllObservers () продолжает делать вызовы при переключении просмотров -Swift2 iOS

Я прочитал другой переполнение стека q & a об этой проблеме, но, похоже, проблема с tabBarController, в которой я ничего не нашел.

У меня есть tabBarController с 3 вкладками. tab1 – это место, где я успешно отправляю информацию в Firebase. В tab2 у меня есть tableView, который успешно считывает данные из tab1.

В tab2 мой слушатель находится в viewWillAppear. Я удаляю слушателя в 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 ничего не делает. Я просто использую его как альтернативную вкладку для переключения туда и обратно с помощью

Solutions Collecting From Web of "Firebase removeAllObservers () продолжает делать вызовы при переключении просмотров -Swift2 iOS"

Метод removeAllObservers работает правильно. Проблема, которую вы сейчас испытываете, вызвана незначительной недостающей деталью: вы никогда не очищаете содержимое sneakerArray .


Примечание: во время обратного вызова события нет необходимости dispatch_async . Firebase SDK вызывает эту функцию в главной очереди.

Официальный принятый ответ был отправлен @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 Slack, и именно там я разместил этот вопрос и 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) } 

Спасибо, что задали этот вопрос.

Я также сталкивался с такой же проблемой в прошлом. Я решил эту проблему следующим образом.

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.