UICollectionView 和它的 collectionViewLayout 之间是不是存在保留周期?

Posted

技术标签:

【中文标题】UICollectionView 和它的 collectionViewLayout 之间是不是存在保留周期?【英文标题】:Is there a retain cycle between UICollectionView and it's collectionViewLayout?UICollectionView 和它的 collectionViewLayout 之间是否存在保留周期? 【发布时间】:2016-08-17 23:07:55 【问题描述】:

根据UICollectionView和UICollectionViewLayout的类引用,UICollectionView持有对其collectionViewLayout属性的强引用,UICollectionViewLayout也持有对其collectionView属性的强引用。

在 UICollectionView 中,

@property(nonatomic, strong) UICollectionViewLayout *collectionViewLayout

在 UICollectionViewLayout 中,(strong 是默认属性)。

@property(nonatomic, readonly) UICollectionView *collectionView   

这里看起来像一个保留周期。为什么 UICollectionViewLayout 不持有对 collectionView 的弱引用?

【问题讨论】:

strong 永远不是只读属性的默认属性,因为只读属性没有任何支持 ivar,strongweak 仅适用于支持 ivar。 UICollectionViewLayout 可能保留其父 UICollectionViewweak 引用,并从 readonly 属性的 getter 中返回它,从而避免保留循环。 【参考方案1】:

在 UICollectionViewLayout 中,(strong 是默认属性)。

@property(nonatomic, readonly) UICollectionView *collectionView

这是默认设置,但 readonly 属性没有存储空间,它只是一个 getter。在内部,布局必须对集合视图具有弱引用。我对其实际源代码一无所知,但它可能看起来像这样:

@interface UICollectionViewLayout ()
@property(nonatomic, weak, readwrite) UICollectionView *collectionView;
@end

但是,如果您运行 Instruments 并确实发现了泄漏,您应该提交雷达,因为这绝对是我书中的一个错误。

【讨论】:

好答案!但是只读属性总是没有存储空间吗?如果 readonly 属性的 getter 没有实现,并且该属性没有在内部重新声明为 readwrite,它会有一个 ivar,对吧? 哦,我正要回答“否”,但看起来编译器确实会自动合成带有 ivar 的 readonly 属性。 ? 我会尝试在运行时找到一个东西来检查 ivar 是否强大,我现在也很好奇。如果我发现任何东西,我会更新答案。 谢谢!我认为它应该很强大。 我认为你是对的。我确实找到了class_getWeakIvarLayout,但实际使用它并不是一个简单的方法,如果有人想更深入地挖掘,我会把它留在那里。【参考方案2】:

正如对Does Objective-C readonly property need to specify retain or copy?、strongweak 的回答中所述,不适用于只读属性——至少不是基于该属性的公开声明。

对于只读属性,真正重要的是它的实际实现方式。该属性很可能在私有类扩展中被重新声明为:

@property (nonatomic, weak, readwrite) UICollectionView *collectionView;

这将避免集合视图与其布局之间的保留循环。

【讨论】:

好答案!因此,如果 readonly 属性没有 getter 并且没有在内部重新声明为 readwrite,strong 也应该适用于该属性,因为它现在有一个 ivar,这是正确的吗? 只读属性只有getter,没有setter。默认情况下,ivar 很强大。 我的意思是它的getter没有实现,所以编译器会为它合成一个ivar。

以上是关于UICollectionView 和它的 collectionViewLayout 之间是不是存在保留周期?的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 与 UIWebView 大小问题

UICollectionView 中的垂直和水平滚动方向

未调用 UIScrollView 内的 UICollectionView 的 didSelectItemAtIndexPath

UIScrollView 中的 UICollectionView 加载所有单元格

UICollectionView - 如果选择了单元格,则不调用 didDeselectItemAtIndexPath

UICollectionView 如何找到单元格最终所在的行