Swift NSInternalInconsistencyException при перезагрузке раздела таблицы в главном потоке - PullRequest
0 голосов
/ 30 апреля 2019

У меня есть UITableView, который обращается к своим данным косвенно (т. Е. Он поддерживается структурой данных указателей) и асинхронно перезагружает свои секции всякий раз, когда новые данные извлекаются с удаленного сервера. Кажется, моя схема перезагрузки имеет состояние гонки; хотя я выполняю только перезагрузки табличного представления в основном потоке, иногда я вижу следующую ошибку:

Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «Неверное обновление: недопустимое количество строк в разделе 1. Количество строк, содержащихся в существующем разделе после обновления (1), должно быть равно количеству строк содержится в этом разделе до обновления (0), плюс или минус количество строк, вставленных или удаленных из этого раздела (0 вставлено, 0 удалено) и плюс или минус количество строк, перемещенных в или из этого раздела (0 перемещено в , 0 переехал).

Мой код структурирован следующим образом:

var table_data_indirect_1: [CustomDataPointer] = []
var table_data_indirect_2: [CustomDataPointer] = []

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let x = customData(in: indexPath.section)[indexPath.row], let cell = table.dequeueReusableCell(withIdentifier: "custom-identifier", for: indexPath) as? CustomCell {
        cell.setCustomData(to: x)
        return cell
    } else {
        return UITableViewCell()
    }
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return customData(in: section).count
}

 func numberOfSections(in: UITableView) -> Int {
    return 2
}

func customData(in section: Int) -> [CustomDataStruct] {        
    switch section {
    case 0:
        return table_data_indirect_1.map { asyncLoadCustomData($0, for: section) }
    case 1:            
        return table_data_indirect_2.map { asyncLoadCustomData($0, for: section) }
    default:
        return []
    }
}

func asyncLoadCustomData(_ customDataPointer: CustomDataPointer, for section: Int) -> CustomDataStruct {
    if customDataPointer.isLoaded {
        return customDataPointer.backingStruct
    } else {
        customDataPointer.asyncLoad { result in
            DispatchQueue.main.async { [weak self] in
                let section_set = IndexSet(integersIn: section...section)
                self?.table.reloadSections(section_set, with: .none)
            }
        }
        return customDataPointer.placeholderStruct
    }
}
...