Verify exported modules only once to support dynamic context in DEBUG-mode
Summary: **Motivation:** We have a project that dynamically changes classes in runtime. This component is initialised within the React Native context. Therefor `RCTBatchedBridge` copies the classes before changes are made to them. While React Native is running, changes are made to the classes dynamically. When the project reloads the `RCTBatchedBridge`, it now has an invalid list of classes containing trash pointers. This causes the project to crash on https://github.com/facebook/react-native/blob/master/React/Base/RCTBatchedBridge.m#L288 with EXC_BAD_ACCESS in the DEBUG-mode. **Solution:** Copy the class list on each reload to get the current state. Since this is only a DEBUG-feature the overhead of this should not be a major issue. Closes https://github.com/facebook/react-native/pull/9541 Differential Revision: D3775012 Pulled By: javache fbshipit-source-id: d55fa0742ca100d8018c73080230cf718aa5a7e9
This commit is contained in:
parent
3fb76696bb
commit
101190f7f8
|
@ -266,38 +266,38 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)dele
|
|||
extraModules = self.moduleProvider();
|
||||
}
|
||||
|
||||
if (RCT_DEBUG && !RCTRunningInTestEnvironment()) {
|
||||
// Check for unexported modules
|
||||
static Class *classes;
|
||||
static unsigned int classCount;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
if (RCT_DEBUG && !RCTRunningInTestEnvironment()) {
|
||||
// Check for unexported modules
|
||||
Class *classes;
|
||||
unsigned int classCount;
|
||||
classes = objc_copyClassList(&classCount);
|
||||
});
|
||||
|
||||
NSMutableSet *moduleClasses = [NSMutableSet new];
|
||||
[moduleClasses addObjectsFromArray:RCTGetModuleClasses()];
|
||||
[moduleClasses addObjectsFromArray:[extraModules valueForKeyPath:@"class"]];
|
||||
NSMutableSet *moduleClasses = [NSMutableSet new];
|
||||
[moduleClasses addObjectsFromArray:RCTGetModuleClasses()];
|
||||
[moduleClasses addObjectsFromArray:[extraModules valueForKeyPath:@"class"]];
|
||||
|
||||
for (unsigned int i = 0; i < classCount; i++)
|
||||
{
|
||||
Class cls = classes[i];
|
||||
Class superclass = cls;
|
||||
while (superclass)
|
||||
for (unsigned int i = 0; i < classCount; i++)
|
||||
{
|
||||
if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule)))
|
||||
Class cls = classes[i];
|
||||
Class superclass = cls;
|
||||
while (superclass)
|
||||
{
|
||||
if (![moduleClasses containsObject:cls] &&
|
||||
![cls respondsToSelector:@selector(moduleName)]) {
|
||||
RCTLogWarn(@"Class %@ was not exported. Did you forget to use "
|
||||
"RCT_EXPORT_MODULE()?", cls);
|
||||
if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule)))
|
||||
{
|
||||
if (![moduleClasses containsObject:cls] &&
|
||||
![cls respondsToSelector:@selector(moduleName)]) {
|
||||
RCTLogWarn(@"Class %@ was not exported. Did you forget to use "
|
||||
"RCT_EXPORT_MODULE()?", cls);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
superclass = class_getSuperclass(superclass);
|
||||
}
|
||||
superclass = class_getSuperclass(superclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
NSMutableArray<Class> *moduleClassesByID = [NSMutableArray new];
|
||||
NSMutableArray<RCTModuleData *> *moduleDataByID = [NSMutableArray new];
|
||||
|
|
Loading…
Reference in New Issue