UICollectionViewData中的断言失败indexPathForItemAtGlobalIndex

Dan*_*ohn 27 objective-c ios uicollectionview

我正在使用performBatchUpdates()来更新我的集合视图,我正在进行完全刷新,即删除其中的任何内容并重新插入所有内容.批量更新是作为附加到()的Observer的一部分完成的.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];
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到这个错误,但不是所有的时间(为什么?)

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
Run Code Online (Sandbox Code Playgroud)

我在这里检查了唯一提到相同问题的线程:UICollectionView断言失败,但不是很清楚,即[collectionview reloadData]performBatchUpdates()块中不建议这样做.

关于这里可能出现什么问题的任何建议?

Ash*_*Ash 20

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

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

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

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

  • 优秀.这是正确的答案!无项目部分很惨. (2认同)

dee*_*ing 17

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

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

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

(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
Run Code Online (Sandbox Code Playgroud)

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

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

希望这可以帮助!

  • 如果我仍然希望节标题可见,即使该节是空的,该怎么办? (2认同)

cze*_*boy 8

reloadData对我来说不起作用,因为使用的整个目的performBatchUpdates是让动画更改.如果您reloadData只使用刷新数据,但没有动画.

因此,"替换performBatchUpdatesreloadData"的建议几乎就是说"放弃你想要做的事情."

对不起,我只是感到沮丧,因为这个错误不断出现,而我正在尝试做一些很棒的动画更新,我的模型是100%正确的,这是一些iOS魔法内部破坏,迫使我改变我的解决方案完全

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

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

  • 谢谢,阿什.我基本上使用了你的解决方案(覆盖prepareForCollectionViewUpdates:但是从不调用super.我只是将它包装在try/catch中.在我完成的一点点测试中,这似乎是有效的.将它包装起来@try {} @ catch {}有额外的好处,当错误修复后,我不需要改变任何东西. (3认同)
  • 我在4周前做到了,他们将其标记为重复,原始的bug仍然是开放的.所以这看起来不太好. (2认同)

小智 3

我也遇到了同样的问题。

我尝试了多种变体,但似乎有效的最后一种是[self.collectionView reloadData]"self.collectionView"集合视图的名称在哪里。

我直接从“UICollectionView类参考”中尝试了以下方法:插入、移动和删除项目。

这些最初用于将项目从一个部分“移动”到另一个部分。

  • deleteItemsAtIndexPaths:

  • insertItemsAtIndexPaths:

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

他们都产生了以下错误:

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

因此,尝试“reloadData”方法。