Skip to content

Commit

Permalink
iOS: add moduleForNameForcedLoad: to lookup modules by name and force…
Browse files Browse the repository at this point in the history
… load them

Summary:
Some module classes may not be loaded yet, so looking up via classes may not always give the correct instance. This diff added a new lookup method that delegate to the bridge delegate to force load the modules as needed.

The existing moduleForName: method was left untouched because it's solely used by RCTUIManager at the moment.

Reviewed By: dshahidehpour

Differential Revision: D13033876

fbshipit-source-id: 4082fcd68498004f678b4b95adc82b5b134fefdf
  • Loading branch information
fkgozali authored and facebook-github-bot committed Nov 14, 2018
1 parent 8826d8b commit d7a0c44
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
4 changes: 4 additions & 0 deletions React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,12 @@ RCT_EXTERN void RCTEnableJSINativeModule(BOOL enabled);
* lazily instantiated, so calling these methods for the first time with a given
* module name/class may cause the class to be sychronously instantiated,
* potentially blocking both the calling thread and main thread for a short time.
*
* Note: This method does NOT lazily load the particular module if it's not yet loaded.
*/
- (id)moduleForName:(NSString *)moduleName;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
// Note: This method lazily load the module as necessary.
- (id)moduleForClass:(Class)moduleClass;

/**
Expand Down
5 changes: 5 additions & 0 deletions React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ - (id)moduleForName:(NSString *)moduleName
return [self.batchedBridge moduleForName:moduleName];
}

- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
return [self.batchedBridge moduleForName:moduleName lazilyLoadIfNecessary:lazilyLoad];
}

- (id)moduleForClass:(Class)moduleClass
{
id module = [self.batchedBridge moduleForClass:moduleClass];
Expand Down
32 changes: 23 additions & 9 deletions React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -439,24 +439,38 @@ - (id)moduleForName:(NSString *)moduleName
return _moduleDataByName[moduleName].instance;
}

- (BOOL)moduleIsInitialized:(Class)moduleClass
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance;
}
if (!lazilyLoad) {
return [self moduleForName:moduleName];
}

- (id)moduleForClass:(Class)moduleClass
{
NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
RCTModuleData *moduleData = _moduleDataByName[moduleName];
if (moduleData) {
return moduleData.instance;
}

// Module may not be loaded yet, so attempt to force load it here.
RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], @"Asking for a NativeModule that doesn't conform to RCTBridgeModule: %@", NSStringFromClass(moduleClass));
[self registerAdditionalModuleClasses:@[moduleClass]];
const BOOL result = [self.delegate respondsToSelector:@selector(bridge:didNotFindModule:)] &&
[self.delegate bridge:self didNotFindModule:moduleName];
if (result) {
// Try again.
moduleData = _moduleDataByName[moduleName];
} else {
RCTLogError(@"Unable to find module for %@", moduleName);
}

return _moduleDataByName[moduleName].instance;
return moduleData.instance;
}

- (BOOL)moduleIsInitialized:(Class)moduleClass
{
return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance;
}

- (id)moduleForClass:(Class)moduleClass
{
return [self moduleForName:RCTBridgeModuleNameForClass(moduleClass) lazilyLoadIfNecessary:YES];
}

- (std::shared_ptr<ModuleRegistry>)_buildModuleRegistryUnlocked
Expand Down

0 comments on commit d7a0c44

Please sign in to comment.