Avoid dispatch_async in RCTRootView when bridge has already started

Summary:
There's no good reason for initialProperties to be mutable after the RCTRootView has been created. Passing it in through the constructor means we can skip one dispatch_async.
This commit is contained in:
Pieter De Baets 2015-08-17 04:38:19 -07:00
parent 8460db57bc
commit 261f9434e5
5 changed files with 31 additions and 25 deletions

View File

@ -30,7 +30,8 @@
launchOptions:launchOptions]; launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"UIExplorerApp"]; moduleName:@"UIExplorerApp"
initialProperties:nil];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [[UIViewController alloc] init]; UIViewController *rootViewController = [[UIViewController alloc] init];

View File

@ -82,6 +82,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
@autoreleasepool { @autoreleasepool {
RCTRootView *view = [[RCTRootView alloc] initWithBundleURL:nil RCTRootView *view = [[RCTRootView alloc] initWithBundleURL:nil
moduleName:@"" moduleName:@""
initialProperties:nil
launchOptions:nil]; launchOptions:nil];
weakBridge = view.bridge; weakBridge = view.bridge;
XCTAssertNotNil(weakBridge, @"RCTBridge should have been created"); XCTAssertNotNil(weakBridge, @"RCTBridge should have been created");
@ -180,7 +181,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
launchOptions:nil]; launchOptions:nil];
__weak UIView *rootContentView; __weak UIView *rootContentView;
@autoreleasepool { @autoreleasepool {
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@""]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"" initialProperties:nil];
RUN_RUNLOOP_WHILE(!(rootContentView = [rootView valueForKey:@"contentView"])) RUN_RUNLOOP_WHILE(!(rootContentView = [rootView valueForKey:@"contentView"]))
XCTAssertTrue(rootContentView.userInteractionEnabled, @"RCTContentView should be valid"); XCTAssertTrue(rootContentView.userInteractionEnabled, @"RCTContentView should be valid");
(void)rootView; (void)rootView;

View File

@ -87,8 +87,7 @@ RCT_NOT_IMPLEMENTED(-init)
moduleProvider:_moduleProvider moduleProvider:_moduleProvider
launchOptions:nil]; launchOptions:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProps];
rootView.initialProperties = initialProps;
rootView.frame = CGRectMake(0, 0, 320, 2000); // Constant size for testing on multiple devices rootView.frame = CGRectMake(0, 0, 320, 2000); // Constant size for testing on multiple devices
NSString *testModuleName = RCTBridgeModuleNameForClass([RCTTestModule class]); NSString *testModuleName = RCTBridgeModuleNameForClass([RCTTestModule class]);

View File

@ -29,7 +29,8 @@ extern NSString *const RCTContentDidAppearNotification;
* - Designated initializer - * - Designated initializer -
*/ */
- (instancetype)initWithBridge:(RCTBridge *)bridge - (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName NS_DESIGNATED_INITIALIZER; moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;
/** /**
* - Convenience initializer - * - Convenience initializer -
@ -40,6 +41,7 @@ extern NSString *const RCTContentDidAppearNotification;
*/ */
- (instancetype)initWithBundleURL:(NSURL *)bundleURL - (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions; launchOptions:(NSDictionary *)launchOptions;
/** /**
@ -60,7 +62,7 @@ extern NSString *const RCTContentDidAppearNotification;
* The default properties to apply to the view when the script bundle * The default properties to apply to the view when the script bundle
* is first loaded. Defaults to nil/empty. * is first loaded. Defaults to nil/empty.
*/ */
@property (nonatomic, copy) NSDictionary *initialProperties; @property (nonatomic, copy, readonly) NSDictionary *initialProperties;
/** /**
* The class of the RCTJavaScriptExecutor to use with this view. * The class of the RCTJavaScriptExecutor to use with this view.

View File

@ -58,6 +58,7 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
- (instancetype)initWithBridge:(RCTBridge *)bridge - (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
{ {
RCTAssertMainThread(); RCTAssertMainThread();
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView"); RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
@ -69,6 +70,7 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
_bridge = bridge; _bridge = bridge;
_moduleName = moduleName; _moduleName = moduleName;
_initialProperties = [initialProperties copy];
_loadingViewFadeDelay = 0.25; _loadingViewFadeDelay = 0.25;
_loadingViewFadeDuration = 0.25; _loadingViewFadeDuration = 0.25;
@ -81,7 +83,7 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
selector:@selector(hideLoadingView) selector:@selector(hideLoadingView)
name:RCTContentDidAppearNotification name:RCTContentDidAppearNotification
object:self]; object:self];
if (!_bridge.batchedBridge.isLoading) { if (!_bridge.loading) {
[self bundleFinishedLoading:_bridge.batchedBridge]; [self bundleFinishedLoading:_bridge.batchedBridge];
} }
@ -92,13 +94,14 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
- (instancetype)initWithBundleURL:(NSURL *)bundleURL - (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions launchOptions:(NSDictionary *)launchOptions
{ {
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:bundleURL RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:bundleURL
moduleProvider:nil moduleProvider:nil
launchOptions:launchOptions]; launchOptions:launchOptions];
return [self initWithBridge:bridge moduleName:moduleName]; return [self initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
} }
RCT_NOT_IMPLEMENTED(-initWithFrame:(CGRect)frame) RCT_NOT_IMPLEMENTED(-initWithFrame:(CGRect)frame)
@ -158,30 +161,30 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder)
- (void)javaScriptDidLoad:(NSNotification *)notification - (void)javaScriptDidLoad:(NSNotification *)notification
{ {
RCTBridge *bridge = notification.userInfo[@"bridge"]; RCTBridge *bridge = notification.userInfo[@"bridge"];
[self bundleFinishedLoading:bridge]; dispatch_async(dispatch_get_main_queue(), ^{
[self bundleFinishedLoading:bridge];
});
} }
- (void)bundleFinishedLoading:(RCTBridge *)bridge - (void)bundleFinishedLoading:(RCTBridge *)bridge
{ {
dispatch_async(dispatch_get_main_queue(), ^{ if (!bridge.valid) {
if (!bridge.isValid) { return;
return; }
}
[_contentView removeFromSuperview]; [_contentView removeFromSuperview];
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds bridge:bridge]; _contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds bridge:bridge];
_contentView.backgroundColor = self.backgroundColor; _contentView.backgroundColor = self.backgroundColor;
[self insertSubview:_contentView atIndex:0]; [self insertSubview:_contentView atIndex:0];
NSString *moduleName = _moduleName ?: @""; NSString *moduleName = _moduleName ?: @"";
NSDictionary *appParameters = @{ NSDictionary *appParameters = @{
@"rootTag": _contentView.reactTag, @"rootTag": _contentView.reactTag,
@"initialProps": _initialProperties ?: @{}, @"initialProps": _initialProperties ?: @{},
}; };
[bridge enqueueJSCall:@"AppRegistry.runApplication" [bridge enqueueJSCall:@"AppRegistry.runApplication"
args:@[moduleName, appParameters]]; args:@[moduleName, appParameters]];
});
} }
- (void)layoutSubviews - (void)layoutSubviews