Allocate RCTRootView.reactTag when it's first requested, instead of waiting until bundle has loaded.

Reviewed By: javache

Differential Revision: D2931937

fb-gh-sync-id: 1cc421a30028e3de1b2d22143edd645d8a34e4d4
shipit-source-id: 1cc421a30028e3de1b2d22143edd645d8a34e4d4
This commit is contained in:
Nick Lockwood 2016-02-12 08:31:54 -08:00 committed by facebook-github-bot-9
parent 3781bf974d
commit 313d84d507
1 changed files with 40 additions and 24 deletions

View File

@ -38,10 +38,11 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
@interface RCTRootContentView : RCTView <RCTInvalidating>
@property (nonatomic, readonly) BOOL contentHasAppeared;
@property (nonatomic, readonly, strong) RCTTouchHandler *touchHandler;
- (instancetype)initWithFrame:(CGRect)frame bridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithFrame:(CGRect)frame
bridge:(RCTBridge *)bridge
reactTag:(NSNumber *)reactTag NS_DESIGNATED_INITIALIZER;
@end
@ -74,6 +75,11 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
_loadingViewFadeDuration = 0.25;
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(bridgeDidReload)
name:RCTJavaScriptWillStartLoadingNotification
object:_bridge];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(javaScriptDidLoad:)
name:RCTJavaScriptDidLoadNotification
@ -83,6 +89,7 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
selector:@selector(hideLoadingView)
name:RCTContentDidAppearNotification
object:self];
if (!_bridge.loading) {
[self bundleFinishedLoading:_bridge.batchedBridge];
}
@ -165,6 +172,29 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
}
}
- (NSNumber *)reactTag
{
RCTAssertMainThread();
if (!super.reactTag) {
/**
* Every root view that is created must have a unique react tag.
* Numbering of these tags goes from 1, 11, 21, 31, etc
*
* NOTE: Since the bridge persists, the RootViews might be reused, so the
* react tag must be re-assigned every time a new UIManager is created.
*/
self.reactTag = [_bridge.uiManager allocateRootTag];
}
return super.reactTag;
}
- (void)bridgeDidReload
{
RCTAssertMainThread();
// Clear the reactTag so it can be re-assigned
self.reactTag = nil;
}
- (void)javaScriptDidLoad:(NSNotification *)notification
{
RCTAssertMainThread();
@ -179,7 +209,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
}
[_contentView removeFromSuperview];
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds bridge:bridge];
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds
bridge:bridge
reactTag:self.reactTag];
[self runApplication:bridge];
_contentView.backgroundColor = self.backgroundColor;
@ -247,11 +279,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
[_delegate rootViewDidChangeIntrinsicSize:self];
}
- (NSNumber *)reactTag
{
return _contentView.reactTag;
}
- (void)contentViewInvalidated
{
[_contentView removeFromSuperview];
@ -291,10 +318,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
- (instancetype)initWithFrame:(CGRect)frame
bridge:(RCTBridge *)bridge
reactTag:(NSNumber *)reactTag
{
if ((self = [super initWithFrame:frame])) {
_bridge = bridge;
[self setUp];
self.reactTag = reactTag;
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
[self addGestureRecognizer:_touchHandler];
[_bridge.uiManager registerRootView:self];
self.layer.backgroundColor = NULL;
}
return self;
@ -337,21 +368,6 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder:(nonnull NSCoder *)aDecoder)
return _backgroundColor;
}
- (void)setUp
{
/**
* Every root view that is created must have a unique react tag.
* Numbering of these tags goes from 1, 11, 21, 31, etc
*
* NOTE: Since the bridge persists, the RootViews might be reused, so now
* the react tag is assigned every time we load new content.
*/
self.reactTag = [_bridge.uiManager allocateRootTag];
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
[self addGestureRecognizer:_touchHandler];
[_bridge.uiManager registerRootView:self];
}
- (void)invalidate
{
if (self.userInteractionEnabled) {