Skip to content

Commit ff66600

Browse files
zienagfacebook-github-bot
authored andcommitted
Use constructor attribute instead of +load objc method (#24155)
Summary: Xcode 10.2 forbids creating categories for swift class that uses `+load` method. In react-native categories like this are used to register swift classes as modules (macro `RCT_EXTERN_MODULE`) This PR changes it to use `__attribute__((constructor))` instead of objc `+load` method. I introduced new macro for this purpose, `RCT_EXPORT_MODULE_NO_LOAD`, it expands in something like: ``` void RCTRegisterModule(Class); + (NSString *)moduleName { return @"jsNameFoo"; } __attribute__((constructor)) static void initialize_ObjcClassFoo{ RCTRegisterModule([ObjcClassFoo class]); } ``` Functions marked with `__attribute__((constructor))` are run before main and after all `+load` methods, so it seems like correct thing to do. Fixes #24139 Doc about loading order https://developer.apple.com/documentation/objectivec/nsobject/1418815-load?language=objc [iOS] [Fixed] - Fix runtime crash in xcode 10.2 when using RCT_EXTERN_MODULE for swift classes. Pull Request resolved: #24155 Reviewed By: javache Differential Revision: D14668235 Pulled By: shergin fbshipit-source-id: 0c19e69ce2a68327387809773848d4ecd36d7461
1 parent 46944b7 commit ff66600

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

React/Base/RCTBridgeModule.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ RCT_EXTERN void RCTRegisterModule(Class); \
7373
+ (NSString *)moduleName { return @#js_name; } \
7474
+ (void)load { RCTRegisterModule(self); }
7575

76+
/**
77+
* Same as RCT_EXPORT_MODULE, but uses __attribute__((constructor)) for module
78+
* registration. Useful for registering swift classes that forbids use of load
79+
* Used in RCT_EXTERN_REMAP_MODULE
80+
*/
81+
#define RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name) \
82+
RCT_EXTERN void RCTRegisterModule(Class); \
83+
+ (NSString *)moduleName { return @#js_name; } \
84+
__attribute__((constructor)) static void \
85+
RCT_CONCAT(initialize_, objc_name)() { RCTRegisterModule([objc_name class]); }
86+
7687
/**
7788
* To improve startup performance users may want to generate their module lists
7889
* at build time and hook the delegate to merge with the runtime list. This
@@ -250,7 +261,7 @@ RCT_EXTERN void RCTRegisterModule(Class); \
250261
@interface objc_name (RCTExternModule) <RCTBridgeModule> \
251262
@end \
252263
@implementation objc_name (RCTExternModule) \
253-
RCT_EXPORT_MODULE(js_name)
264+
RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name)
254265

255266
/**
256267
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods

0 commit comments

Comments
 (0)