Clean up Flipper's iOS layout invalidation

Summary:
This reverts D21285438 and patches some holes in the layout invalidation routines.

(I tried to use `didAddSubview:` and `willRemoveSubview:` but those are annoying for other reasons; for example, `willRemoveSubview:` can be called from within `dealloc` which is surprising. Also they still don't catch the case where subviews are being reordered.)

Reviewed By: Andrey-Mishanin

Differential Revision: D21512129

fbshipit-source-id: 1d9e8dac9333eddfae2309d446ef4de9e83220d6
This commit is contained in:
Adam Ernst
2020-05-12 05:52:36 -07:00
committed by Facebook GitHub Bot
parent 258b0314f5
commit 82898b784e
3 changed files with 59 additions and 30 deletions

View File

@@ -384,10 +384,6 @@
});
}
- (void)invalidateRootNode {
[self invalidateNode:_rootNode];
}
- (void)_reportInvalidatedObjects {
NSMutableArray* nodes = [NSMutableArray new];
{ // scope mutex acquisition

View File

@@ -10,7 +10,6 @@
@protocol SKInvalidationDelegate
- (void)invalidateNode:(id<NSObject>)node;
- (void)invalidateRootNode;
- (void)updateNodeReference:(id<NSObject>)node;
@end

View File

@@ -23,6 +23,30 @@ FB_LINKABLE(UIView_SKInvalidation)
[self class], @selector(setHidden:), @selector(swizzle_setHidden:));
swizzleMethods(
[self class], @selector(addSubview:), @selector(swizzle_addSubview:));
swizzleMethods(
[self class],
@selector(bringSubviewToFront:),
@selector(swizzle_bringSubviewToFront:));
swizzleMethods(
[self class],
@selector(sendSubviewToBack:),
@selector(swizzle_sendSubviewToBack:));
swizzleMethods(
[self class],
@selector(insertSubview:atIndex:),
@selector(swizzle_insertSubview:atIndex:));
swizzleMethods(
[self class],
@selector(insertSubview:aboveSubview:),
@selector(swizzle_insertSubview:aboveSubview:));
swizzleMethods(
[self class],
@selector(insertSubview:belowSubview:),
@selector(swizzle_insertSubview:belowSubview:));
swizzleMethods(
[self class],
@selector(exchangeSubviewAtIndex:withSubviewAtIndex:),
@selector(swizzle_exchangeSubviewAtIndex:withSubviewAtIndex:));
swizzleMethods(
[self class],
@selector(removeFromSuperview),
@@ -30,14 +54,6 @@ FB_LINKABLE(UIView_SKInvalidation)
});
}
/**
This function takes in a view and returns true if the view is a UIWindow and its
windowLevel is an alert one otherwise it returns false.
*/
static auto shouldInvalidateRootNode(UIView* view) -> bool {
return [view isKindOfClass:[UIWindow class]];
}
- (void)swizzle_setHidden:(BOOL)hidden {
[self swizzle_setHidden:hidden];
@@ -50,16 +66,40 @@ static auto shouldInvalidateRootNode(UIView* view) -> bool {
- (void)swizzle_addSubview:(UIView*)view {
[self swizzle_addSubview:view];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
id<SKInvalidationDelegate> delegate =
[SKInvalidation sharedInstance].delegate;
if (delegate != nil) {
if (shouldInvalidateRootNode(view.superview)) {
[delegate invalidateRootNode];
return;
}
[delegate invalidateNode:view.superview];
}
- (void)swizzle_bringSubviewToFront:(UIView*)subview {
[self swizzle_bringSubviewToFront:subview];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
- (void)swizzle_sendSubviewToBack:(UIView*)subview {
[self swizzle_sendSubviewToBack:subview];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
- (void)swizzle_insertSubview:(UIView*)subview atIndex:(NSInteger)index {
[self swizzle_insertSubview:subview atIndex:index];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
- (void)swizzle_insertSubview:(UIView*)subview
aboveSubview:(UIView*)siblingSubview {
[self swizzle_insertSubview:subview aboveSubview:siblingSubview];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
- (void)swizzle_insertSubview:(UIView*)subview
belowSubview:(UIView*)siblingSubview {
[self swizzle_insertSubview:subview belowSubview:siblingSubview];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
- (void)swizzle_exchangeSubviewAtIndex:(NSInteger)index1
withSubviewAtIndex:(NSInteger)index2 {
[self swizzle_exchangeSubviewAtIndex:index1 withSubviewAtIndex:index2];
[[SKInvalidation sharedInstance].delegate invalidateNode:self];
}
- (void)swizzle_removeFromSuperview {
@@ -68,14 +108,8 @@ static auto shouldInvalidateRootNode(UIView* view) -> bool {
// before any early returns or mischief below!
[self swizzle_removeFromSuperview];
id<SKInvalidationDelegate> delegate =
[SKInvalidation sharedInstance].delegate;
if (delegate != nil && oldSuperview != nil) {
if (shouldInvalidateRootNode(oldSuperview)) {
[delegate invalidateRootNode];
return;
}
[delegate invalidateNode:oldSuperview];
if (oldSuperview) {
[[SKInvalidation sharedInstance].delegate invalidateNode:oldSuperview];
}
}