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
{
for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.hasInstance && [moduleData.instance respondsToSelector:@selector(partialBatchDidFlush)]) {
if (moduleData.implementsPartialBatchDidFlush) {
[self dispatchBlock:^{
[moduleData.instance partialBatchDidFlush];
} 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?
for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.hasInstance && [moduleData.instance respondsToSelector:@selector(batchDidComplete)]) {
if (moduleData.implementsBatchDidComplete) {
[self dispatchBlock:^{
[moduleData.instance batchDidComplete];
} queue:moduleData.methodQueue];

View File

@ -63,4 +63,15 @@
*/
@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

View File

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