diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index c98e3648b..310e2e7c8 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -873,15 +873,19 @@ static id _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)]; diff --git a/React/Base/RCTRootView.m b/React/Base/RCTRootView.m index f631af636..980d253d3 100644 --- a/React/Base/RCTRootView.m +++ b/React/Base/RCTRootView.m @@ -11,6 +11,7 @@ #import +#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 diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index df90ff150..7d6925b12 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -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;