带有自定义布局的 UICollectionView 变为空白

UICollectionView with Custom Layout Going Blank

我为使用带有自定义 UICollectionViewLayout 的 UICollectionView 的人构建了一个电视指南样式的应用程序。自定义布局使用四种不同的自定义 UICollectionViewCells。我 运行 遇到了一个非常有趣的问题,这个问题困扰着我和我的团队。我的 post 很长,但这样做是为了希望为您提供完整的上下文。如果你有时间阅读并把你的想法扔给我。我将不胜感激。一如既往,感谢 SO 社区的所有帮助。

tl;dr - 具有自定义布局的 UICollectionView(UICollectionViewLayout 的子类)随机丢失视图中的所有数据。完全空白。 .reloadData()viewDidAppear 上被调用但没有修复。对原因感到困惑。

第 0 节,项目 0 是一种单元格,始终位于左上角。当您滚动时,单元格会随着您移动并保留在左上角。

第 0 节第 1-n 项是第二种类型的单元格,始终位于顶部。

第 1-n 节,第 0-n 项是 "stations",另一种类型的单元格,始终保持在左边框。

所有其他单元格都是 "shows" 和第四种类型的单元格,并根据时间和站点映射到特定的 x,y 坐标。

这个 collectionView 的性能非常好,让我们能够在很大程度上提供出色的用户体验。但是,当完全加载了 10 天的数据时。它使用相当数量的内存。 ~100-150MB,具体取决于阵容、站台数量和演出时长。较短的显示意味着更多的单元格映射到 collection 视图。

当应用程序是 运行 大量指南数据时,有时 collectionView 会打嗝并且我的浮动 headers 会停止移动。然后 ALL 我的细胞就会消失。我们亲切地开始称其为 死亡白屏,因为整个 collection 都呈现为空。此时,滚动条仍然可见,您可以看到自己在滚动,但没有加载任何单元格。

我们已经用连接到 Xcode 的调试器的设备制造了几次问题,并且有一些数据。用于填充所有单元格的数据仍然可以从调试器获得。 cellForItemAtIndexPath 可以从调试器调用,returns 一个 UICollectionViewCell。从调试器打印时,numberOfSectionsnumberOfItemsInSections 仍然有效并显示正确的数字。 cellForItemAtIndexPath 函数在 collection 变空后永远不会被调用。永远不会命中此方法中的断点。布局仍然可以访问,并且可以毫无问题地访问变量。

现在对于看起来不正常的事情,但我们不知道该怎么办。

collectionView.contentSizecollectionView.collectionViewLayout.contentSize是不一样的。在 non-broke 设备上,通过调试器查看时它们是相同的。

collectionView.visibleCells returns 一个空数组。这在技术上是正确的,因为我们的 collection 处于死亡模式的白屏...但是我们有部分和部分中的项目,所以不确定。

问题是间歇性的,但如果我们足够努力,我们通常可以每小时重现几次。我们认为它与内存有关,因为它永远不会发生在模拟器上。仅在物理设备上。

由于这是面向客户的未发布应用,我已将其导航控件涂黑。

有没有人遇到过类似的问题?有没有人对下一步尝试什么有任何想法?

最后一点,感谢您阅读到这里! :)

看到有人刚刚对这个问题投了赞成票,我想我会回来 post 我们达成的决议。

我们的 collectionView 正在调用一个管理应用程序大量数据的单例。当用户滚动以将数据保留在视图中时,单例正在后台填充。这些对单例的后台更新都是通过低优先级的后台线程 运行 管理的。我们构建线程首先更新数据存储,然后更新访问器方法以了解新数据。这是我们在线程安全方面的尝试,因为访问者在数据修改完成之前不会知道除了已经存在的数据之外还有任何其他数据。但是,这没有用。更多详情如下。

在对多个设备进行广泛测试后,我们意识到我们的问题在某些日子里出现的次数非常多,我们获取了这些数据并开始分析给定日期的 collectionView 单元格,我们发现这些日子当问题经常出现时,生成的单元格尺寸非常大,例如,一行中的单个单元格可能跨越 4-5 部 iPhone 的宽度。经过一番搜索,我们发现这是人们普遍遇到的问题,大多数人只是缩小了他们的细胞。然而,我们的细胞与时间和长度相关联。

我们进行了更多研究,最终决定移除所有线程。这意味着当我们的用户到达集合的末尾时,我们将推送一个显示 activity 指示符的模态视图,并在单例更新时阻止用户输入。 立即 解决了我们的问题。

我们的研究笔记:

  • 非常大的单元格、宽度或高度,会导致 collectionView 出现问题,应格外小心。
  • 这些大蜂窝会使问题发生的频率比正常情况高得多,但是,它们似乎并不是我们问题的原因。
  • 线程安全是我们的问题,在某些时候 collectionView 失去了与数据源的连接并且无法恢复。我们尝试了多种补救措施来重新链接数据源,none 奏效了。解决方法是删除所有线程。

希望对您有所帮助!