Swift: укажите допустимое определение раздела, когда для раздела будет отображаться контент. Это ошибка клиента

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

Я инициализирую все в конфигурации контроллера представления и вызываю функцию reloadView каждый раз, когда обновляю исходные данные.

Приложение вылетает из-за следующей ошибки, как только я вызываю функцию reloadView. Но только если до этого представление коллекции было пустым. Если там уже есть предметы, все работает отлично.

Assertion failure in -[_UICollectionCompositionalLayoutSolver _queryClientForSectionDefintionForSectionIndex:]


Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid section definition. Please specify a valid section definition when content is to be rendered for a section. This is a client error.'

Вот как выглядит мой код:


private func configureHierarchy() {

        let layout = collectionViewHelper.createLayout(structure: self.structure)

        collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
        collectionView.delegate = self

        collectionView.register(RecentCollectionViewCell.self, forCellWithReuseIdentifier: RecentCollectionViewCell.reuseIdentifier)
        collectionView.register(OverviewCollectionViewCell.self, forCellWithReuseIdentifier: OverviewCollectionViewCell.reuseIdentifier)
        collectionView.register(MessageItemCollectionViewCell.self, forCellWithReuseIdentifier: MessageItemCollectionViewCell.reuseIdentifier)
        view.addSubview(collectionView)
    }

private func configureDataSource() {

        dataSource = UICollectionViewDiffableDataSource<SectionType, Int>(collectionView: collectionView) {
            (collectionView: UICollectionView, indexPath: IndexPath, cellIndex: Int) -> UICollectionViewCell? in

            let sectionItem = self.structure[indexPath.section]

            switch sectionItem.type{
                //Returns a collection view cell of the specific type
            case .recent:
                return getRecentItemCell(...)
            case .overview:
                return getOverviewItemCell(...)
            case .message:
                return getMessageItemCell(...)
            default:
                return nil
            }
        }
    }

Я применяю снимок вот так

private func applySnapshot(structure:[SectionItem]) {
        var snapshot = NSDiffableDataSourceSnapshot<SectionType, Int>()
        var itemOffset = 0

        for structurItem in structure {
            snapshot.appendSections([structurItem.type])
            snapshot.appendItems(Array(itemOffset..<itemOffset + structurItem.items))
            itemOffset += structurItem.items
        }

        dataSource.apply(snapshot, animatingDifferences: false)
    }

Я делаю это один раз в своей конфигурации

structure = createStructure()
configureHierarchy()
configureDataSource()
applySnapshot(structure: createStructure())

Это функция перезагрузки, которую я вызываю каждый раз, когда данные меняются (ошибка выдается, если раньше данные не отображались)

func reloadView() {
        structure = createStructure()
        applySnapshot(structure: structure)
    }

Есть идеи, почему это так? Уже большое спасибо!

6 ответов

В моем случае источник данных настроен неправильно. Я возвращаю больше разделов, чем на самом деле предоставил в UICollectionViewCompositionalLayout(sectionProvider: sectionProvider).

В моем случае UICollectionViewCompositionalLayout не удаляется в памяти, он продолжает работать, когда мой контроллер уже удален.

private func configureLayout() {
    let layout = UICollectionViewCompositionalLayout { [weak self] (sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
        return self?.layoutSection(sectionIndex: sectionIndex, layoutEnvironment: layoutEnvironment)
    }
    self.collectionView.collectionViewLayout = layout
}

это мой код

Вот int _UICollectionCompositionalLayoutSolver! Это не имеет ничего общего с вашим распространяемым источником данных. Вероятно, вы еще не завершили реализацию своего составного макета. Это то, что только что случилось со мной:) Это просто случай, когда возникает исключение.

Подобно ответу Хорена, в моем случае в моей реализации произошла утечка памяти. Вместо контроллера представления, содержащего ссылку на источник данных, у меня был другой объект, реализующий и содержащий ссылку на источник данных. В конечном итоге это вызвало циклическое обращение к памяти (утечка памяти).

Решение заключалось в том, что когда контроллер представления был отклонен (возможно, на viewDidDisappear), я установил datasource = nil; следовательно, прерывая цикл циклической ссылки и избегая этой ошибки.

у меня такой же вылет при звонке reloadData(), как-то замыкание на моем UICollectionViewCompositionalLayout(sectionProvider:)вернул старые разделы.

Как я исправил это звонил collectionView.collectionViewLayout.invalidateLayout()до перезагрузки.

в этой функции частная функция applySnapshot(структура:[SectionItem]) использует applySnapshot с sectionIdentifier

Другие вопросы по тегам