UICollectionViewData中的断言失败indexPathForItemAtGlobalIndex

时间:2012-12-16 18:05:41

标签: objective-c ios uicollectionview

我正在使用 performBatchUpdates()来更新我的集合视图,我正在进行完全刷新,即删除其中的内容并重新插入所有内容。批量更新是作为观察者的一部分完成的,附加到NSMutableArraybingDataItems)。

cellItems 是包含将要或将要插入到集合视图中的项目的数组。

以下是代码:

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    cultARunner *_cultARunner = [cultARunner getInstance];
    if ( [[_cultARunner bingDataItems] count] ) {
        [self.collectionView reloadData];
        [[self collectionView] performBatchUpdates: ^{

            int itemSize = [cellItems count];
            NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];

            // first delete the old stuff
            if (itemSize == 0) {
                [arrayWithIndexPaths addObject: [NSIndexPath indexPathForRow: 0 inSection: 0]];
            }
            else {
                for( int i = 0; i < cellItems.count; i++ ) {
                    [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
                }
            }
            [cellItems removeAllObjects];
            if(itemSize) {
                [self.collectionView deleteItemsAtIndexPaths:arrayWithIndexPaths];
            }

            // insert the new stuff
            arrayWithIndexPaths = [NSMutableArray array];
            cellItems = [_cultARunner bingDataItems];
            if ([cellItems count] == 0) {
                [arrayWithIndexPaths addObject: [NSIndexPath indexPathForRow: 0 inSection: 0]];
            }
            else {              
                for( int i = 0; i < [cellItems count]; i++ ) {
                    [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
                }
            }
            [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
        }
        completion:nil];
    }
}

我收到此错误,但不是所有时间(为什么?)

2012-12-16 13:17:59.789 [16807:19703] *** Assertion failure in -[UICollectionViewData indexPathForItemAtGlobalIndex:], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionViewData.m:442
2012-12-16 13:17:59.790 [16807:19703] DEBUG:    request for index path for global index 1342177227 when there are only 53 items in the collection view

我在这里检查了唯一提到相同问题的主题:UICollectionView Assertion failure,但不是很清楚,即在[collectionview reloadData]块中不建议performBatchUpdates()

有关此处可能出现的问题的任何建议吗?

8 个答案:

答案 0 :(得分:20)

最后!好的,这就是导致我崩溃的原因。

如前所述,我正在创建补充视图,以便为我的集合视图提供自定义样式的节标题。

问题在于:补充视图的indexPath似乎必须对应于集合中现有单元的indexPath。如果补充视图的索引路径没有对应的普通单元,则应用程序将崩溃。我相信在更新过程中,集合视图会出于某种原因尝试检索补充视图单元格的信息。当它找不到时会崩溃。

希望这也能解决你的问题!

答案 1 :(得分:17)

这是此次崩溃的正确解决方法:

您的每个补充视图都与某个索引路径相关联。如果在索引路径中没有单元格(初始加载,您已删除行等),请通过布局的委托为补充视图返回高度0。

因此,对于流布局,实现UICollectionViewDelegateFlowLayout的

(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

方法(以及相应的页脚方法,如果您使用的是页脚),具有以下逻辑

if ( you-have-a-cell-at-the-row-for-this-section )
    return myNormalHeaderSize;
else return CGSizeMake( 0,0 );

希望这有帮助!

答案 2 :(得分:8)

reloadData对我不起作用,因为使用performBatchUpdates的全部目的是让动画更改动画。如果您使用reloadData,则只刷新数据,但没有动画。

所以“将performBatchUpdates替换为reloadData”的建议几乎就是说“放弃你想要做的事情。”

对不起,我很沮丧,因为这个错误一直在为我而努力,而我正在尝试做一些很棒的动画更新,我的模型是100%正确的,这是一些iOS魔法内部破坏并强迫我完全改变我的解决方案。

我的观点是,收集视图仍然是错误的,无法做复杂的动画刷新,即使他们应该能够。因为对于表视图来说这曾经是相同的事情,但现在它们非常稳定(虽然需要时间)。

//编辑(2013年9月1日) 报告的错误现在已经关闭,所以这个问题似乎已经被Apple解决了。

答案 3 :(得分:3)

我遇到了同样的问题。

我尝试了很多变体,但最后一个似乎有用[self.collectionView reloadData],其中"self.collectionView"是您的集合视图的名称。

我已经尝试了以下方法,直接来自“UICollectionView类参考”:插入,移动和删除项目。

首先使用它们将项目从一个部分“移动”到另一个部分。

  • deleteItemsAtIndexPaths:

  • insertItemsAtIndexPaths:

接下来,我尝试了moveItemAtIndexPath:toIndexPath:

他们都产生了以下错误:

  

断言失败 - [UICollectionViewData indexPathForItemAtGlobalIndex:],/ SourceCache / UIKit_Sim / UIKit-2372 / UICollectionViewData.m:442

所以,试试“reloadData”方法。

答案 4 :(得分:2)

如果从包含页眉/页脚的部分中删除最后一个单元格,则会出现错误。

我当时尝试为页眉/页脚大小/元素返回nil,而有时修复了这个问题。

选项:

  1. 重新加载整个表格视图,而不是动画删除最后一个项目。
  2. 添加一个尺寸小于1的其他不可见的基本单元格。

答案 5 :(得分:2)

可能导致此错误的cheeseball错误是在同一个viewcontroller上的多个collectionView上重用相同的UICollectionViewFlowLayout!只需为每个集合视图初始化不同的flowLayouts,您就可以开始了!

答案 6 :(得分:1)

当我从我的集合视图中删除其中一个单元格时遇到了这个问题。

问题在于我使用自定义布局,并且调用layoutAttributesForElementsInRect返回的内容超过了删除后集合视图中的单元格数。

显然UICollectionView只是遍历方法返回的数组而不检查单元格数。

修改方法以返回相同数量的布局属性,解决了崩溃问题。

答案 7 :(得分:0)

我仍然无法弄清楚全局索引是如何增加的,但我通过在基础数据源数组中插入一个临时项来解决我的问题,即cellItems并在{{[self.collectionview reloadData]中调用viewDidLoad() 1}}。

这会暂时在集合视图中插入占位符单元格,直到我使用performBatchUpdates()触发实际流程。