UICollectionViewController Layout Property (self.collectionView.collectionViewLayout vs. self.collectionViewLayout)

I have a UICollectionViewController managing a collection view that uses different layouts for different application states. I use -setCollectionViewLayout:animated: to navigate between different layouts. I have a bad access error, and it would help a lot to find out what actually belongs (for example, stores a strong link) in the current layout view of the collection.

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

  • self.collectionView.collectionViewLayout returns a new layout.
  • self.collectionViewLayout still returns the old layout.

This led me to check the Link to the UICollectionView class , which explains this behavior:

collectionViewLayout

The layout object used to initialize the collection view controller. (only for reading)

@property (nonatomic,readonly) UICollectionViewLayout *collectionViewLayout

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

Good. So, self.collectionViewLayout is a weak reference (or is it?) To the original layout, and self.collectionView.collectionViewLayout is a strong reference to the current layout.

To confirm this, I plunged into the debugger, but could not find the actual UICollectionView , supposedly owned by the UICollectionViewController . Instead, the _view collection _view was an instance of UICollectionViewControllerWrapperView . Whaaaat?

All this experience left me with the following questions:

  • Where is the actual UICollectionView stored in the UICollectionViewController ?
  • Does self.collectionViewLayout a strong link to the original layout?
+6
source share
2 answers

Where is the actual UICollectionView stored in the UICollectionViewController?

This is actually none of your business. I want to say, it’s interesting that you found a pointer to a collection view, and you could probably find another by searching the controller view hierarchy. The important thing is that you should let the UICollectionViewController worry about the collection view. I know this is not a satisfactory answer when you are trying to understand why your application crashes, but besides debugging, it is always a good idea to avoid messing with view controller views.

Does self.collectionViewLayout support a strong reference to the original layout?

Judging by the documentation, yes . Objective-C properties are strong by default , and you can see from the property specification that the collectionViewLayout property does not indicate weak , so it should be strong .

The additional data is taken from the documentation you provided, which basically says that the property provides a pointer to the layout that you provided during initialization. He does not say that the property will return nil if you change the layout - it does not respond that the property is not updated and continues to point to the original layout, even if you change the layout.

0
source

Well, I already answered my first question: UICollectionViewControllerWrapperView has an ivar called _subviewCache , which is a mutable array containing the actual UICollectionView at index 0. Weird.

However, I would still like the answer to my second question. It seems to me that the collection view controller does not support a strong reference to the original layout, because its collectionViewLayout (initial layout) property is readonly, and I can’t find the link to the collection view layout when checking the collection view controller in the debugger variables view. However, if so, then how is it held on to the original layout even after the collection view has been replaced by a strong link to the original layout from a strong link to another layout?


Update: It turns out that the bad access crash that I saw was caused by a slightly different issue related to the ownership of the UIDynamicAnimator layout. This is almost certainly an error in the Apple code, and I filed a radar that you can read here (duplication is welcome!):

http://www.openradar.me/15062440

However, none of these questions concern my second question. This does not apply either to me or to my work, but I still welcome and support any real answers, even if they are purely academic at this moment.

+2
source

Source: https://habr.com/ru/post/954449/


All Articles