From 8e5585839728320e8ec259b0d03e0c329247cd17 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 3 Dec 2015 03:19:45 -0800 Subject: [PATCH] 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 --- React/Base/RCTBatchedBridge.m | 4 ++-- React/Base/RCTModuleData.h | 11 +++++++++++ React/Base/RCTModuleData.m | 10 ++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index bbb8fe24a..bb6aff8e4 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -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]; diff --git a/React/Base/RCTModuleData.h b/React/Base/RCTModuleData.h index 540059842..79752ba29 100644 --- a/React/Base/RCTModuleData.h +++ b/React/Base/RCTModuleData.h @@ -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 diff --git a/React/Base/RCTModuleData.m b/React/Base/RCTModuleData.m index 11603850f..011159db8 100644 --- a/React/Base/RCTModuleData.m +++ b/React/Base/RCTModuleData.m @@ -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)]) {