Precompute whether modules respond to batch notification methods

Summary:
public

Looping through every `RCTModuleData` to check whether the module responds to `-batchDidComplete` or `-partialBatchDidFlush` is unnecessarily expensive. We can cache the answer at the time that the module instance is actually initialized.

Reviewed By: tadeuzagallo

Differential Revision: D2717594

fb-gh-sync-id: 274a59ec2d6014ce18c93404ce6b9940c1dc9c32
This commit is contained in:
Justin Spahr-Summers 2015-12-03 03:19:45 -08:00 committed by facebook-github-bot-9
parent 1c57291faa
commit 8e55858397
3 changed files with 23 additions and 2 deletions

View File

@ -804,7 +804,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
- (void)partialBatchDidFlush - (void)partialBatchDidFlush
{ {
for (RCTModuleData *moduleData in _moduleDataByID) { for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.hasInstance && [moduleData.instance respondsToSelector:@selector(partialBatchDidFlush)]) { if (moduleData.implementsPartialBatchDidFlush) {
[self dispatchBlock:^{ [self dispatchBlock:^{
[moduleData.instance partialBatchDidFlush]; [moduleData.instance partialBatchDidFlush];
} queue:moduleData.methodQueue]; } queue:moduleData.methodQueue];
@ -816,7 +816,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
{ {
// TODO: batchDidComplete is only used by RCTUIManager - can we eliminate this special case? // TODO: batchDidComplete is only used by RCTUIManager - can we eliminate this special case?
for (RCTModuleData *moduleData in _moduleDataByID) { for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.hasInstance && [moduleData.instance respondsToSelector:@selector(batchDidComplete)]) { if (moduleData.implementsBatchDidComplete) {
[self dispatchBlock:^{ [self dispatchBlock:^{
[moduleData.instance batchDidComplete]; [moduleData.instance batchDidComplete];
} queue:moduleData.methodQueue]; } queue:moduleData.methodQueue];

View File

@ -63,4 +63,15 @@
*/ */
@property (nonatomic, copy, readonly) NSArray *config; @property (nonatomic, copy, readonly) NSArray *config;
/**
* Whether the receiver has a valid `instance` which implements -batchDidComplete.
*/
@property (nonatomic, assign, readonly) BOOL implementsBatchDidComplete;
/**
* Whether the receiver has a valid `instance` which implements
* -partialBatchDidFlush.
*/
@property (nonatomic, assign, readonly) BOOL implementsPartialBatchDidFlush;
@end @end

View File

@ -39,6 +39,8 @@
if ((self = [super init])) { if ((self = [super init])) {
_instance = instance; _instance = instance;
_moduleClass = [instance class]; _moduleClass = [instance class];
[self cacheImplementedSelectors];
} }
return self; return self;
} }
@ -62,10 +64,18 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
// Initialize queue // Initialize queue
[self methodQueue]; [self methodQueue];
[self cacheImplementedSelectors];
} }
return _instance; return _instance;
} }
- (void)cacheImplementedSelectors
{
_implementsBatchDidComplete = [_instance respondsToSelector:@selector(batchDidComplete)];
_implementsPartialBatchDidFlush = [_instance respondsToSelector:@selector(partialBatchDidFlush)];
}
- (void)setBridgeForInstance:(RCTBridge *)bridge - (void)setBridgeForInstance:(RCTBridge *)bridge
{ {
if ([_instance respondsToSelector:@selector(bridge)]) { if ([_instance respondsToSelector:@selector(bridge)]) {