insertItemsAtIndexPaths 更新错误
-
11-12-2019 - |
题
在 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)之后的现有部分中包含的项目数必须等于更新之前该部分中包含的项目数,再加上或减去该节插入或删除的项目数(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
count(包含新数据)并且在初始更新时也会崩溃。
关于我做错了什么有什么建议吗?
谢谢你,
解决方案
我在这里看到了一些问题。首先,我不确定你为什么要使用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];
}