Интересная проблема с UICollectionView reloadData

При работе с UICollectionView в моем приложении у меня возникла странная проблема, связанная с перезагрузкой данных. После долгих отладочных и аналитических журналов я пришел к выводу, что если за reloadData сразу следует insertItemsAtIndexPaths, гарантируется страшная ошибка ниже:

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

Только для этого всегда существует то, что внутри UICollectionView по-прежнему занят reloadData, когда приходит вызов insertItemsAtIndexPaths. Тот факт, что "collectionView:numberOfItemsInSection" вызывается дважды в строке до завершения insertItemsAtIndexPaths, похоже, поддерживает это, поскольку этот метод никогда не вызывается дважды в строке при вызове других случаев.

Кто-нибудь видел подобное поведение или может подтвердить мой анализ или даже предложить правильное обходное решение?

Обновление: любое да, я убедился, что все соответствующие вызовы происходят в основном потоке.

Обновление 2. Поскольку аргументация о том, чтобы попасть в эту ситуацию вообще, была поставлена ​​под сомнение: я использую Monotouch, и этот код предназначен для хранения общих коллекций .Net Collections это событие в соответствующие вызовы, чтобы привязать UICollectionView к коллекции в синхронизации. Когда исходная коллекция очищается, она реагирует с действием Reset, за которым следует один или несколько действий Add, когда элементы вставлены в него, что приводит к описанной выше проблеме. Надеюсь, это поможет.

Ответ 1

Когда вы вызываете insertItemsAtIndexPaths (removeItemsAtIndexPaths аналогично), вы сообщаете своему коллективу, что его источник данных теперь имеет больше доступных элементов и что он должен вставлять эти доступные элементы по указанным вами указателям.

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

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

Я надеюсь, что вы все еще со мной, потому что здесь ваше решение:

Удалите reloadData до insertItemsAtIndexPaths, так как это нарушает его утверждения и будет генерировать исключения при неправильном использовании. Если вы хотите перезагрузить сборку перед вставкой элементов, убедитесь, что вы выполняете insertItemsAtIndexPaths сразу после изменения элементов в источнике данных.

Прочитайте документацию по этому методу здесь.