在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
计数(包含新数据),并且在初始更新时也会崩溃。
关于我做错了什么的任何建议?
谢谢,
答案 0 :(得分:14)
我在这里看到了一些错误。首先,我不确定你为什么要使用dispatch_sync,我没有太多GCD经验,而且我无法在那里使用它(它似乎挂了,用户界面没有响应)。也许其他人可以提供帮助。其次,在你添加索引路径的循环中,你循环遍历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];
}