gpt4 book ai didi

ios - performBatchUpdates 崩溃的噩梦

转载 作者:技术小花猫 更新时间:2023-10-29 11:18:33 27 4
gpt4 key购买 nike

我在 performBatchUpdates 期间面临崩溃的噩梦在 collection view 上.

问题基本上是这样的:我在服务器的目录中有很多图像。我想在 collection view 上显示这些文件的缩略图 .但缩略图必须从服务器异步 下载。当它们到达时,它们将使用如下方式插入到 Collection View 中:

dispatch_async(dispatch_get_main_queue(),
^{
[self.collectionView performBatchUpdates:^{

if (removedIndexes && [removedIndexes count] > 0) {
[self.collectionView deleteItemsAtIndexPaths:removedIndexes];
}

if (changedIndexes && [changedIndexes count] > 0) {
[self.collectionView reloadItemsAtIndexPaths:changedIndexes];
}

if (insertedIndexes && [insertedIndexes count] > 0) {
[self.collectionView insertItemsAtIndexPaths:insertedIndexes];
}

} completion:nil];
});

问题是这个(我认为)。假设在时间 = 0 时, Collection View 有 10 个项目。然后我向服务器添加了 100 个文件。应用程序看到新文件并开始下载缩略图。随着缩略图的下载,它们将被插入到 Collection View 中。但是因为下载可能需要不同的时间,而且这个下载操作是 asynchronous ,在某一时刻,iOS 将无法跟踪集合中有多少元素,并且整个系统将因这条灾难性的臭名昭著的消息而崩溃。

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (213) must be equal to the number of items contained in that section before the update (154), plus or minus the number of items inserted or deleted from that section (40 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).'

如果我打印数据集上的项目计数,我可以准确地看到 213。因此,数据集与正确的数字匹配,消息是无意义的。

我以前遇到过这个问题,here但那是一个 iOS 7 项目。不知何故,问题现在在 iOS 8 上又出现了,那里的解决方案不起作用,现在数据集同步

最佳答案

听起来您需要做一些额外的工作来对每个动画 group 出现的图像进行批处理。从处理像这样的崩溃开始,performBatchUpdates 的工作方式是

  1. 在调用您的 block 之前,它会仔细检查所有项目计数并通过调用 numberOfItemsInSection 保存它们(这是您的错误消息中的 154)。
  2. 它运行 block ,跟踪插入/删除,并根据插入和删除计算应该的最终项目数。
  3. block 运行后,它会在询问您的数据源 numberOfItemsInSection(这是 213 数字)时仔细检查计算的计数与实际计数。如果不匹配,它将崩溃。

根据您的变量 insertedIndexeschangedIndexes,您根据服务器的下载响应预先计算需要显示哪些内容,然后运行批处理.不过我猜你的 numberOfItemsInSection 方法总是只返回“真实”的项目数。

因此,如果下载在第 2 步完成,当它在“3”中执行健全性检查时,您的号码将不再排队。

最简单的解决方案:等到所有文件都下载完毕,然后执行单个 batchUpdates。可能不是最好的用户体验,但它避免了这个问题。

更难的解决方案:根据需要执行批处理,并跟踪哪些项目已经显示/当前正在与项目总数分开进行动画处理。像这样的东西:

BOOL _performingAnimation;
NSInteger _finalItemCount;

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _finalItemCount;
}

- (void)somethingDidFinishDownloading {
if (_performingAnimation) {
return;
}
// Calculate changes.
dispatch_async(dispatch_get_main_queue(),
^{
_performingAnimation = YES;
[self.collectionView performBatchUpdates:^{

if (removedIndexes && [removedIndexes count] > 0) {
[self.collectionView deleteItemsAtIndexPaths:removedIndexes];
}

if (changedIndexes && [changedIndexes count] > 0) {
[self.collectionView reloadItemsAtIndexPaths:changedIndexes];
}

if (insertedIndexes && [insertedIndexes count] > 0) {
[self.collectionView insertItemsAtIndexPaths:insertedIndexes];
}

_finalItemCount += (insertedIndexes.count - removedIndexes.count);
} completion:^{
_performingAnimation = NO;
}];
});
}

之后唯一要解决的问题是,如果要下载的最后一个项目在动画期间完成(可能有一个方法 performFinalAnimationIfNeeded 您在其中运行,请确保对剩余项目进行最终检查完成 block )

关于ios - performBatchUpdates 崩溃的噩梦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37846653/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com