6

我有一个UICollectionViewController管理一个集合视图,它为不同的应用程序状态使用不同的布局。我-setCollectionViewLayout:animated:用来在不同的布局之间进行转换。我遇到了一个糟糕的访问错误,这将极大地帮助了解集合视图的当前布局实际拥有什么(例如保留对)的引用。strong

调用后-setCollectionViewLayout:animated:,我注意到以下内容(在哪里selfUICollectionViewController

  • self.collectionView.collectionViewLayout返回新布局。
  • self.collectionViewLayout仍然返回旧布局。

这使我检查了UICollectionView 类参考,它解释了这种行为:

集合视图布局

用于初始化集合视图控制器的布局对象。(只读)

@property (nonatomic,readonly) UICollectionViewLayout *collectionViewLayout

讨论
此属性包含您传递给 initWithCollectionViewLayout: 方法的布局对象。此属性中的布局对象不会更新以反映对集合视图本身的更改。您可以使用此属性来引用您最初配置要使用的集合视图的布局对象。

好的。self.collectionViewLayout对初始布局的弱引用(或者是?)也是self.collectionView.collectionViewLayout对当前布局的强引用。

为了确认这一点,我深入调试器,但无法找到实际UICollectionView应该由UICollectionViewController. 相反,集合视图控制器的_view变量是UICollectionViewControllerWrapperView. 哇?

整个经历给我留下了以下问题:

  1. 实际UICollectionView存储在哪里UICollectionViewController
  2. 是否self.collectionViewLayout保留strong对初始布局的引用?
4

2 回答 2

3

好吧,我已经回答了我的第一个问题:UICollectionViewControllerWrapperView有一个名为 的 ivar _subviewCache,它是一个可变数组,包含UICollectionView索引 0 处的实际值。奇怪。

但是,我仍然希望回答我的第二个问题。在我看来,集合视图控制器没有保持对初始布局的强引用,因为它的collectionViewLayout(初始布局)属性是只读的,并且在检查集合视图控制器时我找不到任何对集合视图布局的引用调试器的变量视图。然而,如果是这种情况,即使在集合视图对初始布局的强引用被替换为对不同布局的强引用之后,它如何保持初始布局


更新:事实证明,我看到的错误访问崩溃实际上是由与布局所有权有关的略有不同的问题引起UIDynamicAnimator的。这几乎肯定是 Apple 代码中的一个错误,我已经提交了一个雷达,您可以在此处阅读(欢迎重复!):

http://www.openradar.me/15062440

也就是说,这在技术上都没有解决我的第二个问题。它不再与我或我的工作相关,但我仍然欢迎并支持任何真正的答案,即使它们在这一点上纯粹是学术性的。

于 2013-09-23T20:10:01.670 回答
0

实际的 UICollectionView 存储在 UICollectionViewController 中的什么位置?

这真的不关你的事。我的意思是,有趣的是,您找到了指向集合视图的指针,并且您可能通过搜索控制器的视图层次结构找到另一个。重要的是您应该UICollectionViewController担心集合视图。我知道当您试图找出应用程序崩溃的原因时,这不是一个令人满意的答案,但除了调试之外,避免弄乱视图控制器的视图总是一个好主意。

self.collectionViewLayout 是否保持对初始布局的强引用?

从文档来看,的。Objective-C的属性默认是强的,从属性规范中可以看出,collectionViewLayout属性没有指定weak,所以一定是strong

进一步的证据来自您引用的文档,该文档基本上说该属性提供了指向您在初始化时提供的布局的指针。它并不是说nil如果您更改布局,该属性将返回 - 它不妨碍说该属性未更新并继续指向原始布局,即使您更改布局也是如此。

于 2014-07-10T20:10:06.160 回答