mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-13 09:50:17 +00:00
[ASDisplayNode+Layout] Add check for orphaned nodes after layout transition to clean up. (#336)
It is rare that this code has any effect, but I've discovered a case in which it occurs. This task tracks moving this code to a DEBUG-only assertion: https://github.com/TextureGroup/Texture/issues/335
This commit is contained in:
parent
a9837f2dc8
commit
00013aadab
@ -1,6 +1,7 @@
|
|||||||
## master
|
## master
|
||||||
|
|
||||||
* Add your own contributions to the next release on the line below this with your name.
|
* Add your own contributions to the next release on the line below this with your name.
|
||||||
|
- [ASDisplayNode+Layout] Add check for orphaned nodes after layout transition to clean up. #336. [Scott Goodson](https://github.com/appleguy)
|
||||||
- Fixed an issue where GIFs with placeholders never had their placeholders uncover the GIF. [Garrett Moon](https://github.com/garrettmoon)
|
- Fixed an issue where GIFs with placeholders never had their placeholders uncover the GIF. [Garrett Moon](https://github.com/garrettmoon)
|
||||||
- [Yoga] Implement ASYogaLayoutSpec, a simplified integration strategy for Yoga-powered layout calculation. [Scott Goodson](https://github.com/appleguy)
|
- [Yoga] Implement ASYogaLayoutSpec, a simplified integration strategy for Yoga-powered layout calculation. [Scott Goodson](https://github.com/appleguy)
|
||||||
- Fixed an issue where calls to setNeedsDisplay and setNeedsLayout would stop working on loaded nodes. [Garrett Moon](https://github.com/garrettmoon)
|
- Fixed an issue where calls to setNeedsDisplay and setNeedsLayout would stop working on loaded nodes. [Garrett Moon](https://github.com/garrettmoon)
|
||||||
|
|||||||
@ -817,11 +817,54 @@ ASPrimitiveTraitCollectionDeprecatedImplementation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)_assertSubnodeState
|
||||||
|
{
|
||||||
|
// Verify that any orphaned nodes are removed.
|
||||||
|
// This can occur in rare cases if main thread layout is flushed while a background layout is calculating.
|
||||||
|
|
||||||
|
if (self.automaticallyManagesSubnodes == NO) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *subnodes = [self subnodes];
|
||||||
|
NSArray *sublayouts = _calculatedDisplayNodeLayout->layout.sublayouts;
|
||||||
|
|
||||||
|
auto currentSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
|
||||||
|
capacity:subnodes.count];
|
||||||
|
auto layoutSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
|
||||||
|
capacity:sublayouts.count];;
|
||||||
|
for (ASDisplayNode *subnode in subnodes) {
|
||||||
|
[currentSubnodes addObject:subnode];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ASLayout *sublayout in sublayouts) {
|
||||||
|
id <ASLayoutElement> layoutElement = sublayout.layoutElement;
|
||||||
|
ASDisplayNodeAssert([layoutElement isKindOfClass:[ASDisplayNode class]],
|
||||||
|
@"All calculatedLayouts should be flattened and only contain nodes!");
|
||||||
|
[layoutSubnodes addObject:(ASDisplayNode *)layoutElement];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that all subnodes that occur in the current ASLayout tree are present in .subnodes array.
|
||||||
|
if ([layoutSubnodes isSubsetOfHashTable:currentSubnodes] == NO) {
|
||||||
|
// Note: This should be converted to an assertion after confirming it is rare.
|
||||||
|
NSLog(@"Warning: node's layout includes subnodes that have not been added: node = %@, subnodes = %@, subnodes in layout = %@", self, currentSubnodes, layoutSubnodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that everything in the .subnodes array is present in the ASLayout tree (and correct it if not).
|
||||||
|
[currentSubnodes minusHashTable:layoutSubnodes];
|
||||||
|
for (ASDisplayNode *orphanedSubnode in currentSubnodes) {
|
||||||
|
NSLog(@"Automatically removing orphaned subnode %@, from parent %@", orphanedSubnode, self);
|
||||||
|
[orphanedSubnode removeFromSupernode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)_pendingLayoutTransitionDidComplete
|
- (void)_pendingLayoutTransitionDidComplete
|
||||||
{
|
{
|
||||||
|
[self _assertSubnodeState];
|
||||||
|
|
||||||
// Subclass hook
|
// Subclass hook
|
||||||
[self calculatedLayoutDidChange];
|
[self calculatedLayoutDidChange];
|
||||||
|
|
||||||
// Grab lock after calling out to subclass
|
// Grab lock after calling out to subclass
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user