[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;
|
return _eventDispatcher ?: _batchedBridge.eventDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RCT_BRIDGE_WARN(...) \
|
#define RCT_INNER_BRIDGE_ONLY(...) \
|
||||||
- (void)__VA_ARGS__ \
|
- (void)__VA_ARGS__ \
|
||||||
{ \
|
{ \
|
||||||
RCTLogMustFix(@"Called method \"%@\" on top level bridge. This method should \
|
RCTLogMustFix(@"Called method \"%@\" on top level bridge. This method should \
|
||||||
only be called from bridge instance in a bridge module", @(__func__)); \
|
only be called from bridge instance in a bridge module", @(__func__)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_BRIDGE_WARN(enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args)
|
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
|
||||||
RCT_BRIDGE_WARN(_invokeAndProcessModule:(NSString *)module method:(NSString *)method arguments:(NSArray *)args context:(NSNumber *)context)
|
{
|
||||||
|
[self.batchedBridge enqueueJSCall:moduleDotMethod args:args];
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSString *)method arguments:(NSArray *)args context:(NSNumber *)context)
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -1499,6 +1503,7 @@ RCT_BRIDGE_WARN(_invokeAndProcessModule:(NSString *)module method:(NSString *)me
|
||||||
@"module": method.moduleClassName,
|
@"module": method.moduleClassName,
|
||||||
@"method": method.JSMethodName,
|
@"method": method.JSMethodName,
|
||||||
@"selector": NSStringFromSelector(method.selector),
|
@"selector": NSStringFromSelector(method.selector),
|
||||||
|
@"args": RCTJSONStringify(params ?: [NSNull null], NULL),
|
||||||
});
|
});
|
||||||
} forModule:@(moduleID)];
|
} forModule:@(moduleID)];
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#import <objc/runtime.h>
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
|
#import "RCTAssert.h"
|
||||||
#import "RCTBridge.h"
|
#import "RCTBridge.h"
|
||||||
#import "RCTContextExecutor.h"
|
#import "RCTContextExecutor.h"
|
||||||
#import "RCTEventDispatcher.h"
|
#import "RCTEventDispatcher.h"
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||||
moduleName:(NSString *)moduleName
|
moduleName:(NSString *)moduleName
|
||||||
{
|
{
|
||||||
|
RCTAssertMainThread();
|
||||||
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
|
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
|
||||||
RCTAssert(moduleName, @"A moduleName 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
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
[_contentView removeFromSuperview];
|
[_contentView invalidate];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -212,13 +214,12 @@ RCT_IMPORT_METHOD(ReactNative, unmountComponentAtNodeAndRemoveContainer)
|
||||||
|
|
||||||
- (void)invalidate
|
- (void)invalidate
|
||||||
{
|
{
|
||||||
self.userInteractionEnabled = NO;
|
if (self.isValid) {
|
||||||
}
|
self.userInteractionEnabled = NO;
|
||||||
|
[self removeFromSuperview];
|
||||||
- (void)dealloc
|
[_bridge enqueueJSCall:@"ReactNative.unmountComponentAtNodeAndRemoveContainer"
|
||||||
{
|
args:@[self.reactTag]];
|
||||||
[_bridge enqueueJSCall:@"ReactNative.unmountComponentAtNodeAndRemoveContainer"
|
}
|
||||||
args:@[self.reactTag]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -281,7 +281,7 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewNa
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
for (NSNumber *rootViewTag in _rootViewTags) {
|
for (NSNumber *rootViewTag in _rootViewTags) {
|
||||||
((UIView *)_viewRegistry[rootViewTag]).userInteractionEnabled = NO;
|
[_viewRegistry[rootViewTag] invalidate];
|
||||||
}
|
}
|
||||||
|
|
||||||
_rootViewTags = nil;
|
_rootViewTags = nil;
|
||||||
|
|
Loading…
Reference in New Issue