Adhere to main queue requirements of native modules

Summary:
Certain turbomodules set `requiresMainQueueSetup` to true. This is b/c they use some fancy APIs in setup that need main queue.

TurboModuleManager mostly adhered to this restriction, the only case it didn't is when setting bridge. There is possibility that this happens on JS thread, which would crash the app for these certain TM. This diff fixes that.

Reviewed By: RSNara

Differential Revision: D16921644

fbshipit-source-id: 69b2410550360d3ccb03c0b71fb7dfccb889eda4
This commit is contained in:
Peter Argany 2019-08-21 14:28:16 -07:00 коммит произвёл Facebook Github Bot
Родитель 869ddd701b
Коммит e94f2c3625
1 изменённых файлов: 14 добавлений и 1 удалений

Просмотреть файл

@ -284,6 +284,10 @@ static Class getFallbackClassFromName(const char *name)
*/
@try {
/**
* If module requiresMainQueueSetup, dispatch to main queue. Bridge setup
* may call APIs which are main queue only, which crash if called from
* JS thread.
*
* RCTBridgeModule declares the bridge property as readonly.
* Therefore, when authors of NativeModules synthesize the bridge
* via @synthesize bridge = bridge;, the ObjC runtime generates
@ -291,7 +295,16 @@ static Class getFallbackClassFromName(const char *name)
* generated, so we have have to rely on the KVC API of ObjC to set
* the bridge property of these NativeModules.
*/
[(id)module setValue:_bridge forKey:@"bridge"];
if ([[module class] respondsToSelector:@selector(requiresMainQueueSetup)] &&
[[module class] requiresMainQueueSetup]) {
__weak __typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong __typeof(self) strongSelf = weakSelf;
[(id)module setValue:strongSelf->_bridge forKey:@"bridge"];
});
} else {
[(id)module setValue:_bridge forKey:@"bridge"];
}
} @catch (NSException *exception) {
RCTLogError(
@"%@ has no setter or ivar for its bridge, which is not "