diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index fda250d18d..bdcbcd4e4a 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -107,6 +107,15 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; ASCollectionViewInvalidationStyle _nextLayoutInvalidationStyle; + /** + * Our layer, retained. Under iOS < 9, when collection views are removed from the hierarchy, + * their layers may be deallocated and become dangling pointers. This puts the collection view + * into a very dangerous state where pretty much any call will crash it. So we manually retain our layer. + * + * You should never access this, and it will be nil under iOS >= 9. + */ + CALayer *_retainedLayer; + /** * If YES, the `UICollectionView` will reload its data on next layout pass so we should not forward any updates to it. @@ -248,6 +257,10 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [self registerClass:[_ASCollectionViewCell class] forCellWithReuseIdentifier:kCellReuseIdentifier]; + if (!AS_AT_LEAST_IOS9) { + _retainedLayer = self.layer; + } + return self; }