mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
weakly hold key window for KVO frame listener (#50231)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50231 Changelog: [Internal] RCTDeviceInfo uses KVO to listen to frame changes in the application's keyWindow. On initialization, it reads the global keyWindow and adds itself as a listener. When RCTDeviceInfo is cleaned up, it reads the global keyWindow again, and removes itself as an observer. However, this makes an assumption that the keyWindow is always the same. This is not always true - for example, when a UIAlert is presented, the OS creates a new temporary keyWindow to host the alert in order to make sure it is the first responder. If the cleanup is called then, the app will crash because there is no RCTDeviceInfo observing it. Another example is the LogBox, which also temporarily creates a new keyWindow. The fix is simple, we can capture a reference to the application's keyWindow on initialization, but make sure it is weakly held as the keyWindow is usually managed by iOS. Then, when we remove the listener, it is always guaranteed it is the window that we are observing. Reviewed By: javache, cipolleschi, realsoelynn Differential Revision: D71667722 fbshipit-source-id: 103baf980b79b413fb29e6c3deff81dae33671c0
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8f43ae9370
commit
90fce6398f
@@ -30,6 +30,8 @@ using namespace facebook::react;
|
||||
BOOL _isFullscreen;
|
||||
std::atomic<BOOL> _invalidated;
|
||||
NSDictionary *_constants;
|
||||
|
||||
__weak UIWindow *_applicationWindow;
|
||||
}
|
||||
|
||||
static NSString *const kFrameKeyPath = @"frame";
|
||||
@@ -41,7 +43,8 @@ RCT_EXPORT_MODULE()
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
[RCTKeyWindow() addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
|
||||
_applicationWindow = RCTKeyWindow();
|
||||
[_applicationWindow addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -141,7 +144,7 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
|
||||
|
||||
[RCTKeyWindow() removeObserver:self forKeyPath:kFrameKeyPath];
|
||||
[_applicationWindow removeObserver:self forKeyPath:kFrameKeyPath];
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
|
||||
Reference in New Issue
Block a user