3

在 UICollectionView 中,我正在尝试使用performBatchUpdates:completion对我的网格视图执行更新。我的数据源数组是self.results.

这是我的代码:

dispatch_sync(dispatch_get_main_queue(), ^{

            [self.collectionView performBatchUpdates:^{

                int resultsSize = [self.results count];
                [self.results addObjectsFromArray:newData];

                NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
                if (resultsSize == 0) {
                    [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:0 inSection:0]];
                }

                else {
                    for (int i = 0; i < resultsSize; i++) {
                        [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:resultsSize + i inSection:0]];
                    }
                }

                for (id obj in self.results)
                    [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];

            } completion:nil];

解释我有什么/我在做什么:

当初始插入到集合视图完成时,此代码运行良好。但是,当我将更多数据添加/插入到我的集合视图中(通过更新self.results和调用它)时,会出现以下错误:

*由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第0节中的项目数无效。更新后现有节中包含的项目数(8)必须等于其中包含的项目数更新前的那个部分 (4),加上或减去从该部分插入或删除的项目数(插入 32,删除 0),加上或减去移入或移出该部分的项目数(0 移入,0搬出)。'

我知道这意味着数据源没有正确更新。但是,在查询我的self.results数组时,我看到了新的数据计数。我在第一行使用addObjectsFromArray. 我还将旧结果大小存储在resultsSize. 我使用该变量将新添加的索引路径添加到arrayWithIndexPaths.

现在在添加/插入项目时,我尝试了以下 for 循环:

for (id obj in self.results)这就是我现在正在使用的。它最初可以工作,但会进一步插入崩溃。

for (UIImage *image in newData)最初也可以工作,但进一步插入崩溃。

从函数的名称来看,我相信它insertItemsAtIndexPaths会在没有循环的情况下将所有项目插入这些索引路径。但是,如果没有循环,应用程序在最初尝试填充数据时会崩溃。

我还尝试循环resultsSize + 1直到新self.results计数(包含新数据),并且在初始更新时也会崩溃。

关于我做错了什么的任何建议?

谢谢,

4

1 回答 1

14

我在这里看到了一些错误。首先,我不确定您为什么要使用 dispatch_sync,我对 GCD 没有太多经验,而且我无法在其中使用它(它似乎挂起,并且 UI 没有响应)。也许其他人可以提供帮助。其次,在添加索引路径的循环中,您循环遍历 resultsSize,据我了解,它是更新前数组的大小,这不是您想要的——您希望在resultsSize 并循环到 resultsSize + newData.count。最后,当您调用 insertItemsAtIndexPaths 时,您希望执行一次,而不是循环执行。我试过这个,它可以更新集合视图(我没有从头开始尝试使用空集合视图):

-(void)addNewCells {
    [self.collectionView performBatchUpdates:^{
        int resultsSize = [self.results count];
        [self.results addObjectsFromArray:newData];
        NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
        for (int i = resultsSize; i < resultsSize + newData.count; i++) {
            [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        }
            [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
    }
        completion:nil];
}
于 2012-09-30T23:33:15.783 回答