[ReactNative] Fix RootContentView release when the top-level bridge is held
Summary: The RCTRootView creates a underlying RCTRootContentView that was deallocated when the bridge modules were deallocated. That doesn't work when the bridge is held. @public Test Plan: Launch Groups, put a breakpoint on `-[RCTRootContentView dealloc]`, enter and leave a group page. It should be called now.
This commit is contained in:
parent
a142ed50ff
commit
92d7324f15
|
@ -873,15 +873,19 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
|
|||
return _eventDispatcher ?: _batchedBridge.eventDispatcher;
|
||||
}
|
||||
|
||||
#define RCT_BRIDGE_WARN(...) \
|
||||
#define RCT_INNER_BRIDGE_ONLY(...) \
|
||||
- (void)__VA_ARGS__ \
|
||||
{ \
|
||||
RCTLogMustFix(@"Called method \"%@\" on top level bridge. This method should \
|
||||
only be called from bridge instance in a bridge module", @(__func__)); \
|
||||
}
|
||||
|
||||
RCT_BRIDGE_WARN(enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args)
|
||||
RCT_BRIDGE_WARN(_invokeAndProcessModule:(NSString *)module method:(NSString *)method arguments:(NSArray *)args context:(NSNumber *)context)
|
||||
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
|
||||
{
|
||||
[self.batchedBridge enqueueJSCall:moduleDotMethod args:args];
|
||||
}
|
||||
|
||||
RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSString *)method arguments:(NSArray *)args context:(NSNumber *)context)
|
||||
|
||||
@end
|
||||
|
||||
|
@ -1499,6 +1503,7 @@ RCT_BRIDGE_WARN(_invokeAndProcessModule:(NSString *)module method:(NSString *)me
|
|||
@"module": method.moduleClassName,
|
||||
@"method": method.JSMethodName,
|
||||
@"selector": NSStringFromSelector(method.selector),
|
||||
@"args": RCTJSONStringify(params ?: [NSNull null], NULL),
|
||||
});
|
||||
} forModule:@(moduleID)];
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "RCTAssert.h"
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTContextExecutor.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
moduleName:(NSString *)moduleName
|
||||
{
|
||||
RCTAssertMainThread();
|
||||
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
|
||||
RCTAssert(moduleName, @"A moduleName is required to create an RCTRootView");
|
||||
|
||||
|
@ -150,7 +152,7 @@ RCT_IMPORT_METHOD(ReactNative, unmountComponentAtNodeAndRemoveContainer)
|
|||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[_contentView removeFromSuperview];
|
||||
[_contentView invalidate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -212,13 +214,12 @@ RCT_IMPORT_METHOD(ReactNative, unmountComponentAtNodeAndRemoveContainer)
|
|||
|
||||
- (void)invalidate
|
||||
{
|
||||
self.userInteractionEnabled = NO;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_bridge enqueueJSCall:@"ReactNative.unmountComponentAtNodeAndRemoveContainer"
|
||||
args:@[self.reactTag]];
|
||||
if (self.isValid) {
|
||||
self.userInteractionEnabled = NO;
|
||||
[self removeFromSuperview];
|
||||
[_bridge enqueueJSCall:@"ReactNative.unmountComponentAtNodeAndRemoveContainer"
|
||||
args:@[self.reactTag]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -281,7 +281,7 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewNa
|
|||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
for (NSNumber *rootViewTag in _rootViewTags) {
|
||||
((UIView *)_viewRegistry[rootViewTag]).userInteractionEnabled = NO;
|
||||
[_viewRegistry[rootViewTag] invalidate];
|
||||
}
|
||||
|
||||
_rootViewTags = nil;
|
||||
|
|
Loading…
Reference in New Issue