28

我正在使用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()

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

4

8 回答 8

20

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

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

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

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

于 2013-03-16T21:26:38.057 回答
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 );

希望这可以帮助!

于 2013-08-23T21:07:34.660 回答
8

reloadData doesn't work for me, because the whole purpose of using performBatchUpdates is to get the changes animated. If you use reloadData you only refresh the data, but without animations.

So suggestions of "replace performBatchUpdates with reloadData" is pretty much saying "give up on what you're trying to do."

I'm sorry, I'm just frustrated because this error keeps coming up for me while I'm trying to do some great animated updates and my model is 100 % correct, it's some iOS magic inside getting broken and forcing me to change my solutions completely.

My opinion is that Collection Views are still buggy and can't do complicated animated refreshes, even though they should be able to. Because this used to be the same thing for Table Views but those are now pretty stable (it took time, though).

//Edit (Sep 1, 2013) The reported bug is closed now so this issues seems to have been resolved by Apple already.

于 2013-01-02T15:41:59.653 回答
3

我一直有同样的问题。

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

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

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

  • deleteItemsAtIndexPaths:

  • insertItemsAtIndexPaths:

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

他们都产生了以下错误:

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

所以,试试“reloadData”方法。

于 2012-12-23T06:52:03.553 回答
2

一个可能导致此错误的奶酪球错误是在同一视图控制器上的多个 collectionView 上重用相同的 UICollectionViewFlowLayout!只需为每个 collectionview 初始化不同的 flowLayouts 就可以了!

于 2014-04-25T15:41:01.910 回答
2

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

当时我试图为页眉/页脚大小/元素返回 nil,这有时可以解决问题。

选项:

  1. 重新加载整个表格视图,而不是动画删除最后一个项目。
  2. 添加一个额外的不可见的基本单元,其大小小于 1。
于 2013-04-04T07:59:14.403 回答
1

当我从我的收藏视图中删除一个单元格时,我遇到了这个问题。

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

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

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

于 2013-05-01T02:23:39.033 回答
0

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

这会在集合视图中临时插入一个占位符单元格,直到我使用performBatchUpdates().

于 2012-12-27T03:00:59.387 回答