Skip to content

Commit b7b8836

Browse files
zhongwuzwfacebook-github-bot
authored andcommitted
Implement the nativeID functionality in a more efficient way (facebook#23662)
Summary: Implement TODO, implement the nativeID functionality in a more efficient way instead of searching the whole view tree. [iOS] [Fixed] - Implement the nativeID functionality in a more efficient way Pull Request resolved: facebook#23662 Differential Revision: D14323747 Pulled By: shergin fbshipit-source-id: 3d45dbf53ad2b6adb79b4331600d53b51ede76d4
1 parent 50d095c commit b7b8836

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

React/Modules/RCTUIManager.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ RCT_EXTERN NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplier
135135
*/
136136
- (UIView *)viewForNativeID:(NSString *)nativeID withRootTag:(NSNumber *)rootTag;
137137

138+
/**
139+
* Register a view that is tagged with nativeID as its nativeID prop
140+
*
141+
* @param nativeID the id reference to native component relative to root view.
142+
* @param view the view that is tagged with nativeID as its nativeID prop.
143+
*/
144+
- (void)setNativeID:(NSString *)nativeID forView:(UIView *)view;
145+
138146
/**
139147
* The view that is currently first responder, according to the JS context.
140148
*/

React/Modules/RCTUIManager.m

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ static void RCTTraverseViewNodes(id<RCTComponent> view, void (^block)(id<RCTComp
5050
}
5151
}
5252

53+
static NSString *RCTNativeIDRegistryKey(NSString *nativeID, NSNumber *rootTag)
54+
{
55+
if (!nativeID || !rootTag) {
56+
return @"";
57+
}
58+
return [NSString stringWithFormat:@"%@-%@", rootTag, nativeID];
59+
}
60+
5361
NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification = @"RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification";
5462

5563
@implementation RCTUIManager
@@ -63,6 +71,7 @@ @implementation RCTUIManager
6371

6472
NSMutableDictionary<NSNumber *, RCTShadowView *> *_shadowViewRegistry; // RCT thread only
6573
NSMutableDictionary<NSNumber *, UIView *> *_viewRegistry; // Main thread only
74+
NSMapTable<NSString *, UIView *> *_nativeIDRegistry; // Main thread only
6675

6776
NSMapTable<RCTShadowView *, NSArray<NSString *> *> *_shadowViewsWithUpdatedProps; // UIManager queue only.
6877
NSHashTable<RCTShadowView *> *_shadowViewsWithUpdatedChildren; // UIManager queue only.
@@ -106,6 +115,7 @@ - (void)invalidate
106115
self->_rootViewTags = nil;
107116
self->_shadowViewRegistry = nil;
108117
self->_viewRegistry = nil;
118+
self->_nativeIDRegistry = nil;
109119
self->_bridge = nil;
110120

111121
[[NSNotificationCenter defaultCenter] removeObserver:self];
@@ -131,13 +141,23 @@ - (void)invalidate
131141
return _viewRegistry;
132142
}
133143

144+
- (NSMapTable *)nativeIDRegistry
145+
{
146+
// Should be called on main queue
147+
if (!_nativeIDRegistry) {
148+
_nativeIDRegistry = [NSMapTable strongToWeakObjectsMapTable];
149+
}
150+
return _nativeIDRegistry;
151+
}
152+
134153
- (void)setBridge:(RCTBridge *)bridge
135154
{
136155
RCTAssert(_bridge == nil, @"Should not re-use same UIManager instance");
137156
_bridge = bridge;
138157

139158
_shadowViewRegistry = [NSMutableDictionary new];
140159
_viewRegistry = [NSMutableDictionary new];
160+
_nativeIDRegistry = [NSMapTable strongToWeakObjectsMapTable];
141161

142162
_shadowViewsWithUpdatedProps = [NSMapTable weakToStrongObjectsMapTable];
143163
_shadowViewsWithUpdatedChildren = [NSHashTable weakObjectsHashTable];
@@ -366,31 +386,27 @@ - (void)setLocalData:(NSObject *)localData forView:(UIView *)view
366386
} forTag:view.reactTag];
367387
}
368388

369-
/**
370-
* TODO(yuwang): implement the nativeID functionality in a more efficient way
371-
* instead of searching the whole view tree
372-
*/
373389
- (UIView *)viewForNativeID:(NSString *)nativeID withRootTag:(NSNumber *)rootTag
374390
{
375391
RCTAssertMainQueue();
376-
UIView *view = [self viewForReactTag:rootTag];
377-
return [self _lookupViewForNativeID:nativeID inView:view];
392+
if (!nativeID || !rootTag) {
393+
return nil;
394+
}
395+
return [_nativeIDRegistry objectForKey:RCTNativeIDRegistryKey(nativeID, rootTag)];
378396
}
379397

380-
- (UIView *)_lookupViewForNativeID:(NSString *)nativeID inView:(UIView *)view
398+
- (void)setNativeID:(NSString *)nativeID forView:(UIView *)view
381399
{
382400
RCTAssertMainQueue();
383-
if (view != nil && [nativeID isEqualToString:view.nativeID]) {
384-
return view;
401+
if (!nativeID) {
402+
return;
385403
}
386-
387-
for (UIView *subview in view.subviews) {
388-
UIView *targetView = [self _lookupViewForNativeID:nativeID inView:subview];
389-
if (targetView != nil) {
390-
return targetView;
404+
__weak RCTUIManager *weakSelf = self;
405+
[self rootViewForReactTag:view.reactTag withCompletion:^(UIView *rootView) {
406+
if (rootView) {
407+
[weakSelf.nativeIDRegistry setObject:view forKey:RCTNativeIDRegistryKey(nativeID, rootView.reactTag)];
391408
}
392-
}
393-
return nil;
409+
}];
394410
}
395411

396412
- (void)setSize:(CGSize)size forView:(UIView *)view

React/Views/RCTViewManager.m

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ - (RCTShadowView *)shadowView
105105
RCT_EXPORT_VIEW_PROPERTY(tvParallaxProperties, NSDictionary)
106106
#endif
107107

108-
RCT_EXPORT_VIEW_PROPERTY(nativeID, NSString)
109-
110108
// Acessibility related properties
111109
RCT_REMAP_VIEW_PROPERTY(accessible, reactAccessibilityElement.isAccessibilityElement, BOOL)
112110
RCT_REMAP_VIEW_PROPERTY(accessibilityActions, reactAccessibilityElement.accessibilityActions, NSArray<NSString *>)
@@ -171,6 +169,12 @@ - (RCTShadowView *)shadowView
171169
view.reactAccessibilityElement.accessibilityTraits = (view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityStatesMask) | maskedTraits;
172170
}
173171

172+
RCT_CUSTOM_VIEW_PROPERTY(nativeID, NSString *, RCTView)
173+
{
174+
view.nativeID = json ? [RCTConvert NSString:json] : defaultView.nativeID;
175+
[_bridge.uiManager setNativeID:view.nativeID forView:view];
176+
}
177+
174178
RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView)
175179
{
176180
if ([view respondsToSelector:@selector(setPointerEvents:)]) {

0 commit comments

Comments
 (0)