From 08c404d2939a3c2e75a514da1a7c03151fbb30e7 Mon Sep 17 00:00:00 2001 From: Daniele Conti Date: Mon, 20 Mar 2017 12:40:45 -0700 Subject: [PATCH] Eagerly change the listeners count Summary: While working with `RCTEventEmitter` I noticed that if an event is emitted before `_listenerCount` is updated, it will not go through because the listeners count hasn't been updated. Moving the count update before the invokation of `startObserving` and `stopObserving` fixes the issue. Same way if you remove the last listener and an event is fired before the count is updated (while it shouldn't be fired). **Test plan (required)** An easy test to demonstrate it is to implement `startObserving` to synchronously fire an event. Without the change, a warning is thrown, with the change, the event is fired. Not very strong on Obj-C here and I didn't know how to mock out the native stuff. Would be glad to write a failing unit test tho :) Closes https://github.com/facebook/react-native/pull/11907 Differential Revision: D4738965 Pulled By: javache fbshipit-source-id: cf175051be5b9c5de761d3dcd290560e1639b05e --- React/Modules/RCTEventEmitter.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/React/Modules/RCTEventEmitter.m b/React/Modules/RCTEventEmitter.m index 4cfec6575..9f54f1f49 100644 --- a/React/Modules/RCTEventEmitter.m +++ b/React/Modules/RCTEventEmitter.m @@ -78,10 +78,10 @@ RCT_EXPORT_METHOD(addListener:(NSString *)eventName) RCTLogError(@"`%@` is not a supported event type for %@. Supported events are: `%@`", eventName, [self class], [[self supportedEvents] componentsJoinedByString:@"`, `"]); } - if (_listenerCount == 0) { + _listenerCount++; + if (_listenerCount == 1) { [self startObserving]; } - _listenerCount++; } RCT_EXPORT_METHOD(removeListeners:(NSInteger)count) @@ -89,10 +89,10 @@ RCT_EXPORT_METHOD(removeListeners:(NSInteger)count) if (RCT_DEBUG && count > _listenerCount) { RCTLogError(@"Attempted to remove more %@ listeners than added", [self class]); } - if (count == _listenerCount) { + _listenerCount = MAX(_listenerCount - count, 0); + if (_listenerCount == 0) { [self stopObserving]; } - _listenerCount -= count; } @end