diff --git a/React/Base/RCTModuleData.h b/React/Base/RCTModuleData.h index 40b8d18f7..f1d09408f 100644 --- a/React/Base/RCTModuleData.h +++ b/React/Base/RCTModuleData.h @@ -58,27 +58,14 @@ typedef id(^RCTBridgeModuleProvider)(void); /** * Returns YES if module instance must be created on the main thread. - * May be overriden by "allowOffMainQueueRegistration". */ -@property (nonatomic, assign, readonly) BOOL requiresMainQueueSetup; +@property (nonatomic, assign) BOOL requiresMainQueueSetup; /** * Returns YES if module has constants to export. - * May be overriden by "allowOffMainQueueRegistration". */ @property (nonatomic, assign, readonly) BOOL hasConstantsToExport; -/** - * If set to YES, it will force both setup and constants export process - * to explicitly happen off the main queue. - * Overrides "requiresMainQueueSetup" & "hasConstantsToExport" - * Defaults to NO. - * - * @experimental - */ - -@property (nonatomic, assign) BOOL allowOffMainQueueRegistration; - /** * Returns the current module instance. Note that this will init the instance * if it has not already been created. To check if the module instance exists diff --git a/React/Base/RCTModuleData.mm b/React/Base/RCTModuleData.mm index edad58467..3c850148f 100644 --- a/React/Base/RCTModuleData.mm +++ b/React/Base/RCTModuleData.mm @@ -44,14 +44,15 @@ objectInitMethod = [NSObject instanceMethodForSelector:@selector(init)]; }); - // If a module overrides `init` then we must assume that it expects to be - // initialized on the main thread, because it may need to access UIKit. - _requiresMainQueueSetup = !_instance && - [_moduleClass instanceMethodForSelector:@selector(init)] != objectInitMethod; - // If a module overrides `constantsToExport` then we must assume that it // must be called on the main thread, because it may need to access UIKit. _hasConstantsToExport = [_moduleClass instancesRespondToSelector:@selector(constantsToExport)]; + + // If a module overrides `init` then we must assume that it expects to be + // initialized on the main thread, because it may need to access UIKit. + const BOOL hasCustomInit = !_instance && [_moduleClass instanceMethodForSelector:@selector(init)] != objectInitMethod; + + _requiresMainQueueSetup = _hasConstantsToExport || hasCustomInit; } - (instancetype)initWithModuleClass:(Class)moduleClass @@ -101,7 +102,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); if (!_setupComplete && _bridge.valid) { if (!_instance) { - if (RCT_DEBUG && _requiresMainQueueSetup && !_allowOffMainQueueRegistration) { + if (RCT_DEBUG && _requiresMainQueueSetup) { RCTAssertMainQueue(); } RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge] Create module", nil); @@ -222,7 +223,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); { if (!_setupComplete) { RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData instanceForClass:%@]", _moduleClass]), nil); - if (_requiresMainQueueSetup && !_allowOffMainQueueRegistration) { + if (_requiresMainQueueSetup) { // The chances of deadlock here are low, because module init very rarely // calls out to other threads, however we can't control when a module might // get accessed by client code during bridge setup, and a very low risk of @@ -295,7 +296,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); if (_hasConstantsToExport && !_constantsToExport) { RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData gatherConstants] %@", _moduleClass]), nil); (void)[self instance]; - if (_allowOffMainQueueRegistration) { + if (!_requiresMainQueueSetup) { _constantsToExport = [_instance constantsToExport] ?: @{}; } else { if (!RCTIsMainQueue()) { diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index c8dc9c8e2..1dbc570b3 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -651,7 +651,7 @@ struct RCTInstanceCallback : public InstanceCallback { continue; } - if (moduleData.requiresMainQueueSetup || moduleData.hasConstantsToExport) { + if (moduleData.requiresMainQueueSetup) { // Modules that need to be set up on the main thread cannot be initialized // lazily when required without doing a dispatch_sync to the main thread, // which can result in deadlock. To avoid this, we initialize all of these