From 855d411321119e79f899c7420a5a435506fb6cbf Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Tue, 9 Feb 2016 03:29:18 -0800 Subject: [PATCH] Moved constants export to bridge init Summary: public Lazy export of module constants required a sync dispatch to the main thread, which was deadlocking in some of our projects. This moves the constants export to the initial bridge init, which may slightly increase initial startup time, but avoids the deadlock. Reviewed By: javache Differential Revision: D2911295 fb-gh-sync-id: 0d14a629ac4fc7ee21acd293c09595c18232659b shipit-source-id: 0d14a629ac4fc7ee21acd293c09595c18232659b --- React/Base/RCTBatchedBridge.m | 7 ++++--- React/Base/RCTModuleData.m | 15 ++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index 6ca0fad9c..debc00d9a 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -282,10 +282,11 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void); id module = preregisteredModules[moduleName]; if (!module) { // Check if the module class, or any of its superclasses override init - // or setBridge:. If they do, we assume that they are expecting to be - // initialized when the bridge first loads. + // or setBridge:, or has exported constants. If they do, we assume that + // they are expecting to be initialized when the bridge first loads. if ([moduleClass instanceMethodForSelector:@selector(init)] != objectInitMethod || - [moduleClass instancesRespondToSelector:setBridgeSelector]) { + [moduleClass instancesRespondToSelector:setBridgeSelector] || + RCTClassOverridesInstanceMethod(moduleClass, @selector(constantsToExport))) { module = [moduleClass new]; if (!module) { module = (id)kCFNull; diff --git a/React/Base/RCTModuleData.m b/React/Base/RCTModuleData.m index 9d4b57539..78ef8471e 100644 --- a/React/Base/RCTModuleData.m +++ b/React/Base/RCTModuleData.m @@ -17,6 +17,7 @@ @implementation RCTModuleData { + NSDictionary *_constantsToExport; NSString *_queueName; __weak RCTBridge *_bridge; NSLock *_instanceLock; @@ -79,6 +80,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); [[NSNotificationCenter defaultCenter] postNotificationName:RCTDidInitializeModuleNotification object:_bridge userInfo:@{@"module": _instance}]; + + if (RCTClassOverridesInstanceMethod(_moduleClass, @selector(constantsToExport))) { + RCTAssertMainThread(); + _constantsToExport = [_instance constantsToExport]; + } } } @@ -181,13 +187,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); - (NSArray *)config { - __block NSDictionary *constants; - if (RCTClassOverridesInstanceMethod(_moduleClass, @selector(constantsToExport))) { - [self instance]; - RCTExecuteOnMainThread(^{ - constants = [_instance constantsToExport]; - }, YES); - } + __block NSDictionary *constants = _constantsToExport; + _constantsToExport = nil; // Not needed any more if (constants.count == 0 && self.methods.count == 0) { return (id)kCFNull; // Nothing to export