Skip to content

Commit f4927fc

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
migrate RCTAppState away from main thread initialization (#49476)
Summary: Pull Request resolved: #49476 changelog: [internal] Introduce RCTInitialAppStateProxy to access app initial state in thread safe way. Reviewed By: javache Differential Revision: D69745459 fbshipit-source-id: f88a04774e064bf13904183aa3334f93cbcc5283
1 parent 0e54029 commit f4927fc

File tree

4 files changed

+88
-9
lines changed

4 files changed

+88
-9
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#import <UIKit/UIKit.h>
9+
10+
NS_ASSUME_NONNULL_BEGIN
11+
12+
@interface RCTInitialAppStateProxy : NSObject
13+
14+
+ (instancetype)sharedInstance;
15+
16+
/*
17+
* Property to access initial application state.
18+
* Thread safe.
19+
*/
20+
@property (nonatomic, readonly) UIApplicationState initialAppState;
21+
22+
- (void)recordAppState;
23+
24+
@end
25+
26+
NS_ASSUME_NONNULL_END
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#import "RCTInitialAppStateProxy.h"
9+
#import <React/RCTUtils.h>
10+
#import <mutex>
11+
12+
#import <React/RCTConstants.h>
13+
14+
@implementation RCTInitialAppStateProxy {
15+
BOOL _hasRecordedInitialAppState;
16+
UIApplicationState _initialAppState;
17+
std::mutex _mutex;
18+
}
19+
20+
+ (instancetype)sharedInstance
21+
{
22+
static RCTInitialAppStateProxy *sharedInstance = nil;
23+
static dispatch_once_t onceToken;
24+
dispatch_once(&onceToken, ^{
25+
sharedInstance = [RCTInitialAppStateProxy new];
26+
});
27+
return sharedInstance;
28+
}
29+
30+
- (UIApplicationState)initialAppState
31+
{
32+
{
33+
std::lock_guard<std::mutex> lock(_mutex);
34+
if (_hasRecordedInitialAppState) {
35+
return _initialAppState;
36+
}
37+
}
38+
39+
__block UIApplicationState initialAppState;
40+
RCTUnsafeExecuteOnMainQueueSync(^{
41+
initialAppState = [UIApplication sharedApplication].applicationState;
42+
});
43+
44+
return initialAppState;
45+
}
46+
47+
- (void)recordAppState
48+
{
49+
std::lock_guard<std::mutex> lock(_mutex);
50+
_hasRecordedInitialAppState = YES;
51+
_initialAppState = [UIApplication sharedApplication].applicationState;
52+
}
53+
54+
@end

packages/react-native/React/Base/UIKitProxies/RCTInitializeUIKitProxies.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#import "RCTInitializeUIKitProxies.h"
9+
#import "RCTInitialAppStateProxy.h"
910
#import "RCTTraitCollectionProxy.h"
1011
#import "RCTWindowSafeAreaProxy.h"
1112

@@ -15,5 +16,6 @@ void RCTInitializeUIKitProxies(void)
1516
dispatch_once(&onceToken, ^{
1617
[[RCTWindowSafeAreaProxy sharedInstance] startObservingSafeArea];
1718
[[RCTTraitCollectionProxy sharedInstance] startObservingTraitCollection];
19+
[[RCTInitialAppStateProxy sharedInstance] recordAppState];
1820
});
1921
}

packages/react-native/React/CoreModules/RCTAppState.mm

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#import <React/RCTAssert.h>
1212
#import <React/RCTBridge.h>
1313
#import <React/RCTEventDispatcherProtocol.h>
14+
15+
#import <React/RCTInitialAppStateProxy.h>
1416
#import <React/RCTUtils.h>
1517

1618
#import "CoreModulesPlugins.h"
@@ -31,7 +33,7 @@
3133
return @"extension";
3234
}
3335

34-
return states[@(RCTSharedApplication().applicationState)] ?: @"unknown";
36+
return states[@([RCTInitialAppStateProxy sharedInstance].initialAppState)] ?: @"unknown";
3537
}
3638

3739
@interface RCTAppState () <NativeAppStateSpec>
@@ -45,7 +47,7 @@ @implementation RCTAppState {
4547

4648
+ (BOOL)requiresMainQueueSetup
4749
{
48-
return YES;
50+
return NO;
4951
}
5052

5153
- (dispatch_queue_t)methodQueue
@@ -60,14 +62,9 @@ - (dispatch_queue_t)methodQueue
6062

6163
- (facebook::react::ModuleConstants<JS::NativeAppState::Constants>)getConstants
6264
{
63-
__block facebook::react::ModuleConstants<JS::NativeAppState::Constants> constants;
64-
RCTUnsafeExecuteOnMainQueueSync(^{
65-
constants = facebook::react::typedConstants<JS::NativeAppState::Constants>({
66-
.initialAppState = RCTCurrentAppState(),
67-
});
65+
return facebook::react::typedConstants<JS::NativeAppState::Constants>({
66+
.initialAppState = RCTCurrentAppState(),
6867
});
69-
70-
return constants;
7168
}
7269

7370
#pragma mark - Lifecycle

0 commit comments

Comments
 (0)