Skip to content

Commit

Permalink
[ASCollectionNode/ASTableNode] Fix a crash occurs while remeasuring c…
Browse files Browse the repository at this point in the history
…ell nodes (TextureGroup#917)
  • Loading branch information
nguyenhuy authored May 15, 2018
1 parent 970ebd9 commit 0830f6c
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
- Adds a check that Texture is compiled with stdc++11 as specified by the podfile. gnu++11 can cause subtle issues that are currently being investigated. [Adlai Holler](https://github.com/Adlai-Holler)
- Adds an experiment to call ASNetworkImageNode callbacks off main. [Garrett Moon](https://github.com/garrettmoon)
- Prevent UITextView from updating contentOffset while deallocating [Michael Schneider](https://github.com/maicki)
- [ASCollectionNode/ASTableNode] Fix a crash occurs while remeasuring cell nodes. [Huy Nguyen](https://github.com/nguyenhuy) [#917](https://github.com/TextureGroup/Texture/pull/917)

## 2.6
- [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon)
Expand Down
11 changes: 7 additions & 4 deletions Source/ASCollectionView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1724,11 +1724,14 @@ - (ASScrollDirection)scrollableDirections
- (void)layoutSubviews
{
if (_cellsForLayoutUpdates.count > 0) {
NSMutableArray<ASCellNode *> *nodesSizesChanged = [NSMutableArray array];
[_dataController relayoutNodes:_cellsForLayoutUpdates nodesSizeChanged:nodesSizesChanged];
[self nodesDidRelayout:nodesSizesChanged];
NSArray<ASCellNode *> *nodes = [_cellsForLayoutUpdates allObjects];
[_cellsForLayoutUpdates removeAllObjects];

NSMutableArray<ASCellNode *> *nodesSizeChanged = [NSMutableArray array];

[_dataController relayoutNodes:nodes nodesSizeChanged:nodesSizeChanged];
[self nodesDidRelayout:nodesSizeChanged];
}
[_cellsForLayoutUpdates removeAllObjects];

// Flush any pending invalidation action if needed.
ASCollectionViewInvalidationStyle invalidationStyle = _nextLayoutInvalidationStyle;
Expand Down
14 changes: 7 additions & 7 deletions Source/ASTableView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ @interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegat
// CountedSet because UIKit may display the same element in multiple cells e.g. during animations.
NSCountedSet<ASCollectionElement *> *_visibleElements;

BOOL _remeasuringCellNodes;
NSHashTable<ASCellNode *> *_cellsForLayoutUpdates;

// See documentation on same property in ASCollectionView
Expand Down Expand Up @@ -745,26 +744,27 @@ - (void)waitUntilAllUpdatesAreCommitted
- (void)layoutSubviews
{
// Remeasure all rows if our row width has changed.
_remeasuringCellNodes = YES;
UIEdgeInsets contentInset = self.contentInset;
CGFloat constrainedWidth = self.bounds.size.width - [self sectionIndexWidth] - contentInset.left - contentInset.right;
if (constrainedWidth > 0 && _nodesConstrainedWidth != constrainedWidth) {
_nodesConstrainedWidth = constrainedWidth;
[_cellsForLayoutUpdates removeAllObjects];

[self beginUpdates];
[_dataController relayoutAllNodesWithInvalidationBlock:nil];
[self endUpdatesAnimated:(ASDisplayNodeLayerHasAnimations(self.layer) == NO) completion:nil];
} else {
if (_cellsForLayoutUpdates.count > 0) {
NSMutableArray *nodesSizesChanged = [NSMutableArray array];
[_dataController relayoutNodes:_cellsForLayoutUpdates nodesSizeChanged:nodesSizesChanged];
if (nodesSizesChanged.count > 0) {
NSArray<ASCellNode *> *nodes = [_cellsForLayoutUpdates allObjects];
[_cellsForLayoutUpdates removeAllObjects];

NSMutableArray<ASCellNode *> *nodesSizeChanged = [NSMutableArray array];
[_dataController relayoutNodes:nodes nodesSizeChanged:nodesSizeChanged];
if (nodesSizeChanged.count > 0) {
[self requeryNodeHeights];
}
}
}
[_cellsForLayoutUpdates removeAllObjects];
_remeasuringCellNodes = NO;

// To ensure _nodesConstrainedWidth is up-to-date for every usage, this call to super must be done last
[super layoutSubviews];
Expand Down
2 changes: 1 addition & 1 deletion Source/Details/ASDataController.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ extern NSString * const ASCollectionInvalidUpdateException;
*
* @discussion Used to respond to setNeedsLayout calls in ASCellNode
*/
- (void)relayoutNodes:(id<NSFastEnumeration>)nodes nodesSizeChanged:(NSMutableArray * _Nonnull)nodesSizesChanged;
- (void)relayoutNodes:(id<NSFastEnumeration>)nodes nodesSizeChanged:(NSMutableArray<ASCellNode *> *)nodesSizesChanged;

/**
* See ASCollectionNode.h for full documentation of these methods.
Expand Down
3 changes: 2 additions & 1 deletion Source/Details/ASDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,9 @@ - (void)_insertElementsIntoMap:(ASMutableElementMap *)map

#pragma mark - Relayout

- (void)relayoutNodes:(id<NSFastEnumeration>)nodes nodesSizeChanged:(NSMutableArray *)nodesSizesChanged
- (void)relayoutNodes:(id<NSFastEnumeration>)nodes nodesSizeChanged:(NSMutableArray<ASCellNode *> *)nodesSizesChanged
{
NSParameterAssert(nodes);
NSParameterAssert(nodesSizesChanged);

ASDisplayNodeAssertMainThread();
Expand Down

0 comments on commit 0830f6c

Please sign in to comment.