在我的应用中处理UICollectionView
时,我遇到了与重新加载数据相关的奇怪问题。经过大量的调试和分析日志后,我得出的结论是,如果reloadData
后面紧跟insertItemsAtIndexPaths
,则可以保证发生下面的可怕错误:
名称:
NSInternalInconsistencyException
原因:无效更新:无效 第0节中的项目数。包含在项目中的项目数 更新后的现有部分(1)必须等于数量 更新前的该部分中包含的项目(1),加号或减号 从该部分插入或删除的项目数(插入1个) ...
他们只能始终如一地发生这种情况,即UICollectionView
在reloadData
的呼叫到达时,insertItemsAtIndexPaths
仍然忙于collectionView:numberOfItemsInSection
。在insertItemsAtIndexPaths
完成之前连续两次调用“{{1}}”的事实似乎支持这一点,因为在调用其他情况时,该方法永远不会连续调用两次。
有没有人见过类似的行为,或者可以确认我的分析,甚至建议正确的解决方法?
更新:是的,我确保所有相关的调用都发生在主线程上。
更新2 :由于完全陷入这种情况的原因受到了质疑:我正在使用Monotouch,而且有问题的代码旨在保持通用.Net集合的触发{{3}进入适当的调用以保持UICollectionView与集合同步。清除源集合后,它会响应重置操作,然后在项目插入其中时执行一个或多个添加操作,从而导致上述问题。希望这会有所帮助。
答案 0 :(得分:1)
当您致电insertItemsAtIndexPaths
(removeItemsAtIndexPaths
类似)时,您告诉您的集合视图其数据源现在有更多可用项目,并且它应该在您指定的索引路径中插入这些可用项目。 / p>
它检查你的数据源是否该声明是真的,如果它检测到旧项目的数量加上你说你插入的项目数量不等于新项目的数量,它说它不能做更新,因为你撒谎了你改变了多少项。
现在,你正在做的是你告诉你的集合视图是它应该从其数据源(使用新数据)重新加载它的所有数据,然后就告诉它你插入了x项。这是一个虚假陈述,因为你刚刚重新加载了集合视图,它更新了它的项目数量,因此更新前的项目数量等于更新后的项目数量(你没有做任何事情),并且不会增加您指定的索引路径数量。
我希望你还和我在一起,因为这是你的解决方案:
删除reloadData
之前的insertItemsAtIndexPaths
,因为这会破坏其断言并在错误使用时抛出异常。如果您想在插入项目之前重新加载集合视图,请确保在更改数据源中的项目后立即执行insertItemsAtIndexPaths
。
阅读此方法的文档here。