Call stopObserving on correct queue

Summary:
Since `dealloc` can be called from any thread, this would result `stopObserving` being called on a different thread/queue than the specified `methodQueue`. We specifically encountered this issue with a module needing the main queue having its `stopObserving` called on a background queue.

Changelog:
[iOS][Fixed] - Call [RCTEventEmitter stopObserving] on specified method queue

Reviewed By: RSNara

Differential Revision: D23821741

fbshipit-source-id: 693c3be6876f863da6dd214a829af2cc13a09c3f
This commit is contained in:
Scott Kyle
2020-09-21 17:30:34 -07:00
committed by Facebook GitHub Bot
parent 18f29db5a7
commit 23717e48af
9 changed files with 13 additions and 9 deletions
@@ -46,6 +46,7 @@ RCT_EXPORT_MODULE();
- (void)invalidate
{
[super invalidate];
[_nodesManager stopAnimationLoop];
[self.bridge.eventDispatcher removeDispatchObserver:self];
[self.bridge.uiManager.observerCoordinator removeObserver:self];
@@ -47,6 +47,7 @@ RCT_EXPORT_MODULE();
- (void)invalidate
{
[super invalidate];
[_nodesManager stopAnimationLoop];
[self.bridge.eventDispatcher removeDispatchObserver:self];
[self.bridge.uiManager.observerCoordinator removeObserver:self];
+3 -1
View File
@@ -168,6 +168,8 @@ RCT_EXPORT_MODULE()
- (void)invalidate
{
[super invalidate];
for (NSNumber *requestID in _tasksByRequestID) {
[_tasksByRequestID[requestID] cancel];
}
@@ -680,7 +682,7 @@ RCT_EXPORT_METHOD(sendRequest:(JS::NativeNetworkingIOS::SpecSendRequestQuery &)q
@"timeout": @(query.timeout()),
@"withCredentials": @(query.withCredentials()),
};
// TODO: buildRequest returns a cancellation block, but there's currently
// no way to invoke it, if, for example the request is cancelled while
// loading a large file to build the request body
+1 -1
View File
@@ -7,6 +7,6 @@
#import <React/RCTEventEmitter.h>
@interface RCTAppState : RCTEventEmitter <RCTInvalidating>
@interface RCTAppState : RCTEventEmitter
@end
-5
View File
@@ -99,11 +99,6 @@ RCT_EXPORT_MODULE()
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)invalidate
{
[self stopObserving];
}
#pragma mark - App Notification Methods
- (void)handleMemoryWarning
+1
View File
@@ -202,6 +202,7 @@ RCT_EXPORT_MODULE()
- (void)invalidate
{
[super invalidate];
#if ENABLE_PACKAGER_CONNECTION
[[RCTPackagerConnection sharedPackagerConnection] removeHandler:_reloadToken];
#endif
+2
View File
@@ -53,6 +53,8 @@ RCT_EXPORT_MODULE()
- (void)invalidate
{
[super invalidate];
_contentHandlers = nil;
for (RCTSRWebSocket *socket in _sockets.allValues) {
socket.delegate = nil;
+3 -1
View File
@@ -12,7 +12,7 @@
* RCTEventEmitter is an abstract base class to be used for modules that emit
* events to be observed by JS.
*/
@interface RCTEventEmitter : NSObject <RCTBridgeModule, RCTJSInvokerModule>
@interface RCTEventEmitter : NSObject <RCTBridgeModule, RCTJSInvokerModule, RCTInvalidating>
@property (nonatomic, weak) RCTBridge *bridge;
@@ -37,6 +37,8 @@
- (void)startObserving;
- (void)stopObserving;
- (void)invalidate NS_REQUIRES_SUPER;
- (void)addListener:(NSString *)eventName;
- (void)removeListeners:(double)count;
+1 -1
View File
@@ -78,7 +78,7 @@
// Does nothing
}
- (void)dealloc
- (void)invalidate
{
if (_listenerCount > 0) {
[self stopObserving];