UICollectionViewController的布局(self.collectionView所有權。collectionViewLayout比self.collectionViewLayout) - UICollectionViewControlle

UICollectionViewController的布局(self.collectionView所有權。collectionViewLayout比self.collectionViewLayout) - UICollectionViewControlle,第1张

I have a UICollectionViewController managing a collection view that uses different layouts for different app states. I'm using -setCollectionViewLayout:animated: to transition between the different layouts. I'm having a bad access error, and it would help immensely to know what actually owns (e.g. keeps a strong reference to) the collection view's current layout.


After calling -setCollectionViewLayout:animated:, I've noticed the following (where self is the UICollectionViewController):


  • self.collectionView.collectionViewLayout returns the new layout.
  • self.collectionView。collectionViewLayout返回新的布局。
  • self.collectionViewLayout still returns the old layout.
  • 自我。collectionViewLayout仍然返回舊布局。

This led me to check the UICollectionView Class Reference, which explains this behavior:



The layout object used to initialize the collection view controller. (read-only)


@property (nonatomic,readonly) UICollectionViewLayout *collectionViewLayout

@ property UICollectionViewLayout * collectionViewLayout(原子只讀)

This property contains the layout object you passed to the initWithCollectionViewLayout: method. The layout object in this property is not updated to reflect changes to the collection view itself. You can use this property to refer to the layout object you originally configured the collection view to use.


Okay. So self.collectionViewLayout is a weak reference (or is it?) to the initial layout and self.collectionView.collectionViewLayout is a strong reference to the current layout.


To confirm this, I took a dive into the debugger, but wasn't able to find the actual UICollectionView supposedly owned by the UICollectionViewController. Instead, the collection view controller's _view variable was an instance of UICollectionViewControllerWrapperView. Whaaaat?


This whole experience left me with the following questions:


  1. Where is the actual UICollectionView stored in a UICollectionViewController?
  2. UICollectionViewController中存儲的實際UICollectionView在哪里?
  3. Does self.collectionViewLayout keep a strong reference to the initial layout?
  4. 做自己。collectionViewLayout保留了對初始布局的強烈引用嗎?

2 个解决方案



Where is the actual UICollectionView stored in a UICollectionViewController?


This is really none of your business. I mean, it's interesting that you found a pointer to the collection view, and you could probably find another by searching through the controller's view hierarchy. The important thing is that you should let UICollectionViewController worry about the collection view. I know that's not a satisfying answer when you're trying to figure out why your app is crashing, but aside from debugging it's always a good idea to avoid messing with a view controller's views.


Does self.collectionViewLayout keep a strong reference to the initial layout?


Judging from the documentation, yes. Objective-C properties are strong by default, and you can see from the property specification that the collectionViewLayout property doesn't specify weak, so it must be strong.


Further evidence comes from the documentation you quoted, which basically says that the property provides a pointer to the layout that you provided at initialization. It doesn't say that the property will return nil if you change the layout -- it goes out of the way to say that the property isn't updated and continues to point to the original layout even if you change the layout.