0

Добрый день всем,CollectionView: scrollToItem, reloadData и отправка Очередь

Я сталкиваюсь разочарование ошибки что касается болтая приложения учебника я следующий, и хотел бы исправить (учебник не решает эта проблема, так как я преобразован в Swift 3/Xcode8). Позвольте мне попытаться описать проблему:

Журнал чата между двумя пользователями использует базу данных Firebase для хранения и извлечения сообщений разговора между ними. Я использую collectionView для отображения разговора. Я хотел реализовать функцию в журнале чата, так что когда пользователь выбирает разговор для просмотра, он будет прокручивать последнее/последнее «сообщение», чтобы пользователь мог легко продолжить разговор.

Вот текущий соответствующий код контроллера журнала чата:

func observeMessages() { 
    guard let uid = FIRAuth.auth()?.currentUser?.uid, let toId = user?.id else { 
     return 
    } 

    let userMessagesRef = FIRDatabase.database().reference().child("user-messages").child(uid).child(toId) 
    userMessagesRef.observe(.childAdded, with: { (snapshot) in 

     let messageId = snapshot.key 
     let messagesRef = FIRDatabase.database().reference().child("messages").child(messageId) 
     messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in 

      guard let dictionary = snapshot.value as? [String: AnyObject] else { 
       return 
      } 

      self.messages.append(Message(dictionary: dictionary)) 

      DispatchQueue.main.async(execute: { 
       self.collectionView?.reloadData() 

       let indexPath = IndexPath(item: self.messages.count - 1, section: 0) 

       self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true) 
      }) 

     }, withCancel: nil) 

    }, withCancel: nil) 
} 

Проблема Я сталкиваюсь в отношении к инвалидному indexPath для CollectionView для прокрутки. Используя заявления печати, я обнаружил, что reloadData() получает много вызовов, и это просто мое предположение из консоли отладки, что indexPath не может «обновить» или «не отставать» от значений.

Я совершенно новичок в GCD (мне сказали, что обновления для пользовательского интерфейса всегда должны выполняться в основном потоке), и задавался вопросом, будет ли ответ на мою проблему в настройке правильного синхронного/асинхронного выполнения, или последовательные/параллельные очереди.

Ex // Использовать фоновый поток для извлечения сообщений о разговоре и обновления indexPath, в то время как основной поток асинхронно перезагружаетData и scrollsToItem.

Я не уверен, но если кто-то может пролить свет на это или указать мне в правильном направлении, я бы очень признателен. Большое спасибо.

ответ

1

Если CollectionView на основе

self.messages array, 

поставил

self.messages.append(Message(dictionary: dictionary)) 

в основной поток тоже.

Все ваши списки данных, которые использовались для основных таблиц потоков (collectionView или tableView), должны управляться только в основном потоке.

+0

Спасибо Никита и Санджу. Я внес изменения, и он, похоже, облегчает все проблемы. Я уверен, что с тех пор я буду хранить списки данных в основном потоке. – iMoment