Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ASCollectionNode/ASTableNode] Fix a crash occurs while remeasuring cell nodes #917

Merged
merged 4 commits into from
May 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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