Синхронизация UITableview с данными подписки - PullRequest
0 голосов
/ 23 мая 2019

У меня есть Tableview с довольно сложными операциями, где разделы вставляются и обновляются в реальном времени, хотя Подписки GraphQl .

В настоящий момент у меня возникают некоторые проблемыс условиями гонки .Когда я получаю новые данные по подписке, я анализирую их в моей модели и обновляю табличное представление с помощью вставок и обновляю содержимое и размер в некоторых существующих ячейках.

Проблема возникает, когда я получаю данные быстрее, чем я могу завершить предыдущее обновление в таблице, что приводит к «недопустимому числу секций» сбой.

Я считаю, что решение заключается в serial / wait последовательности подписка -> модель -> просмотр таблицы .

Я пытался заставить это работать с различными методами параллелизма, такими как семафор, синхронизация, барьер, группа диспетчеризации .но не смогли успешно разобраться.

Если я попытаюсь упростить, последовательность событий будет выглядеть примерно так:

// Модель

subscription { data in 

 //should not start parsing new data until previous data has been drawn in table to avoid missmatch in model and table

 parse(data)

}

func parse(data) {
//do stuff like update datamodel 
figureOutWhatToUpdateInTable(data) { (insertSet, reloadSet) in
  delegate.updateTableView(insertSet, reloadSet)
 }
//do stuff
}

// VC

func updateTableView(insertSet, reloadSet) {

 tableView.beginUpdates()
 CATransaction.begin()

//once a new section is inserted we need to update content of some sections  
 CATransaction.setCompletionBlock {

  reloadSet.forEach { (index: Int) in

   let section = tableView.headerView(forSection: index)

    section.updateData(data[index]) {
 // call begin/end to make tableview get height                                                
     tableView.beginUpdates()                                            
     tableView.endUpdates()

// now im ready to parse new data into my model

      }
   })

 }

tableView.insertSections(insetSet, with: .top)
CATransaction.commit()
tableView.endUpdates()

}

в основном мне нужно подождать, пока section.updateData завершится, прежде чем parse (data) обработает все новые данные из подписки

1 Ответ

0 голосов
/ 23 мая 2019

Вы можете использовать в этом случае DispatchGroup

    let group = DispatchGroup()
    group.enter()

    // do some stuff (1)

    group.leave()

    group.notify(queue: .main) {
        // do stuff after 1
    }

После вызова group.leave() группа автоматически выполнит STUFF в group.notify Блок

...