mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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 https://github.com/facebook/react-native/issues/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: https://github.com/facebook/react-native/pull/24155
Reviewed By: javache
Differential Revision: D14668235
Pulled By: shergin
fbshipit-source-id: 0c19e69ce2a68327387809773848d4ecd36d7461
This commit is contained in:
committed by
Lorenzo Sciandra
parent
e94d3444dc
commit
df7ea67313
@@ -73,6 +73,17 @@ RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
+ (NSString *)moduleName { return @#js_name; } \
|
||||
+ (void)load { RCTRegisterModule(self); }
|
||||
|
||||
/**
|
||||
* Same as RCT_EXPORT_MODULE, but uses __attribute__((constructor)) for module
|
||||
* registration. Useful for registering swift classes that forbids use of load
|
||||
* Used in RCT_EXTERN_REMAP_MODULE
|
||||
*/
|
||||
#define RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name) \
|
||||
RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
+ (NSString *)moduleName { return @#js_name; } \
|
||||
__attribute__((constructor)) static void \
|
||||
RCT_CONCAT(initialize_, objc_name)() { RCTRegisterModule([objc_name class]); }
|
||||
|
||||
/**
|
||||
* To improve startup performance users may want to generate their module lists
|
||||
* at build time and hook the delegate to merge with the runtime list. This
|
||||
@@ -250,7 +261,7 @@ RCT_EXTERN void RCTRegisterModule(Class); \
|
||||
@interface objc_name (RCTExternModule) <RCTBridgeModule> \
|
||||
@end \
|
||||
@implementation objc_name (RCTExternModule) \
|
||||
RCT_EXPORT_MODULE(js_name)
|
||||
RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name)
|
||||
|
||||
/**
|
||||
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods
|
||||
|
||||
Reference in New Issue
Block a user