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

Posted

技术标签:

【中文标题】具有自定义布局的 UICollectionView 变为空白【英文标题】:UICollectionView with Custom Layout Going Blank 【发布时间】:2015-06-18 23:01:18 【问题描述】:

我为使用带有自定义 UICollectionViewLayout 的 UICollectionView 的人构建了一个电视指南样式的应用程序。自定义布局使用四个不同的自定义 UICollectionViewCells。我遇到了一个非常有趣的问题,它困扰了我和我的团队。我的帖子很长,但这样做是为了希望为您提供完整的背景信息。如果您有时间阅读并向我提出您的想法。我将不胜感激。一如既往,感谢 SO 社区的所有帮助。

tl;dr - 具有自定义布局(UICollectionViewLayout 的子类)的 UICollectionView 会随机丢失视图中的所有数据。完全空白。 .reloadData()viewDidAppear 上调用,但未修复。不知道是什么原因。

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

Section 0, Item 1-n 是第二种单元格,始终保持在顶部。

第 1-n 部分,第 0-n 项是“站”,另一种类型的单元格,始终沿左边界保留。

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

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

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

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

现在对于那些看起来不正常,但我们不知道如何处理的事情。

collectionView.contentSizecollectionView.collectionViewLayout.contentSize 是不同的。在未损坏的设备上,通过调试器查看时它们是相同的。

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

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

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

有人遇到过类似的问题吗?有人对接下来要尝试什么有任何想法吗?

最后一点,感谢您阅读本文! :)

【问题讨论】:

【参考方案1】:

看到有人刚刚对这个问题投了赞成票,我想我会回来发布我们达成的解决方案。

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

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

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

我们的研究笔记:

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

希望这会有所帮助!

【讨论】:

很酷的调试。我有一个类似的问题,并且在我删除了对单例类的依赖后的最后几天问题没有出现,为视图控制器提供数据。您的研究提供了一些很好的建议。

以上是关于具有自定义布局的 UICollectionView 变为空白的主要内容,如果未能解决你的问题,请参考以下文章

具有自定义布局的 UICollectionView - 无法在情节提要中添加补充视图

自定义UICollectionView布局

UICollectionView 自定义布局单元格类型相关属性

如何 UICollectionView 每列具有不同的行

iOS UICollectionView自定义流水布局(一)

UICollectionView 中的自定义布局