是什么导致了这个 iOS 崩溃?UICollectionView 接收到具有不存在索引路径的单元格的布局属性 [英] What's causing this iOS crash? UICollectionView received layout attributes for a cell with an index path that does not exist

查看:12
本文介绍了是什么导致了这个 iOS 崩溃?UICollectionView 接收到具有不存在索引路径的单元格的布局属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个具有 UICollectionViewController 的应用程序,该应用程序在某些难以重现的神秘情况下崩溃.崩溃日志如下所示:

I'm working on an app that has a UICollectionViewController that is crashing in certain mysterious situations that are hard to reproduce. The log for the crash looks like this:

*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UICollectionViewData.m:417
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0xc000000000008016> {length = 2, path = 0 - 1}'

只有在我们切换到 iOS 8 SDK 后,我们的代码才开始出现类似的崩溃.

Crashes like this only seem to have started occurring in our code once we switched to the iOS 8 SDK.

为什么会这样?

注意:我已经知道问题的答案是什么,但我在 Stack Overflow 和其他网络上发现与此崩溃相关的信息非常少.我将在下面发布答案.这个错误花了我和我的同事三天时间才找到,所以希望这篇文章可以为其他人节省很多时间和挫败感.我已经向 Apple 提交了这个错误.

Note: I already know what the answer to question is, but I found very little information relating to this crash on Stack Overflow and the rest of the web. I'll post the answer below. This bug took my coworker and I three days to track down, so hopefully this post will save someone else a lot of time and frustration. I have filed this bug with Apple.

推荐答案

崩溃发生在以下情况:

我们有一个集合视图控制器,它在其上呈现另一个视图控制器.

We had a collection view controller that was presenting another view controller on top of it.

虽然集合视图控制器不再可见,但在响应我们应用的后端请求时偶尔会发生以下事件序列.

While the collection view controller was no longer visible, the following sequence of events was occasionally occurring in response to our app's back end requests.

  1. [UICollectionView insertItemsAtIndexPaths:] 被调用为 50隐藏 UICollectionViewController 的集合视图上的项目.
  2. [UICollectionView reloadData] 在隐藏的集合视图上被调用.
  3. 会出现短暂的延迟.
  4. 隐藏的集合视图中的项目数设置为较小的数字.
  5. [UICollectionView reloadData] 再次被调用.
  6. 视图控制器被解除,显示隐藏的集合视图控制器.
  1. [UICollectionView insertItemsAtIndexPaths:] was called with 50 items on the collection view of the hidden UICollectionViewController.
  2. [UICollectionView reloadData] was called on the hidden collection view.
  3. A short delay would occur.
  4. The number of items in the hidden collection view was set to a small number.
  5. [UICollectionView reloadData] was called again.
  6. The view controller was dismissed, revealing the hidden collection view controller.

内部 UIKit 类 UICollectionViewData 中的断言失败将在第 6 步发生.

The assertion failure in the internal UIKit class UICollectionViewData would happen at step 6.

因此,教训是,尽量避免操作在屏幕上不可见的集合视图.

So, the lesson is, try to avoid manipulating a collection view that is not visible on the screen.

我们解决此问题的方法是在关键点调用 [UICollectionView reloadSections:] 而不是 [UICollectionView reloadData].

Our workaround for this problem was to call [UICollectionView reloadSections:] instead of [UICollectionView reloadData] at key points.

我们怀疑 reloadData 的影响会推迟到未来的某个时间点,因此在与其他方法调用(如 insertItemsAtIndexPaths)交互方面存在一些微妙的问题,而 reloadSections 会立即处理,从而使集合视图处于更好的状态.

We suspect that the effects of reloadData are deferred to some point in the future, and there are consequently subtle issues with how this may interact with other method calls like insertItemsAtIndexPaths, whereas reloadSections is handled immediately, leaving the collection view in a better state.

我们认为,在开始为 iOS 8 构建应用之前,我们没有看到这种行为.

We think that we were not seeing this behavior until we started building our app for iOS 8.

睡个好觉,我的朋友们!

Sleep well, my friends!

这篇关于是什么导致了这个 iOS 崩溃?UICollectionView 接收到具有不存在索引路径的单元格的布局属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆