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
This commit is contained in:
Daniele Conti 2017-03-20 12:40:45 -07:00 committed by Facebook Github Bot
parent f352aa129a
commit 08c404d293

View File

@ -78,10 +78,10 @@ RCT_EXPORT_METHOD(addListener:(NSString *)eventName)
RCTLogError(@"`%@` is not a supported event type for %@. Supported events are: `%@`", RCTLogError(@"`%@` is not a supported event type for %@. Supported events are: `%@`",
eventName, [self class], [[self supportedEvents] componentsJoinedByString:@"`, `"]); eventName, [self class], [[self supportedEvents] componentsJoinedByString:@"`, `"]);
} }
if (_listenerCount == 0) { _listenerCount++;
if (_listenerCount == 1) {
[self startObserving]; [self startObserving];
} }
_listenerCount++;
} }
RCT_EXPORT_METHOD(removeListeners:(NSInteger)count) RCT_EXPORT_METHOD(removeListeners:(NSInteger)count)
@ -89,10 +89,10 @@ RCT_EXPORT_METHOD(removeListeners:(NSInteger)count)
if (RCT_DEBUG && count > _listenerCount) { if (RCT_DEBUG && count > _listenerCount) {
RCTLogError(@"Attempted to remove more %@ listeners than added", [self class]); RCTLogError(@"Attempted to remove more %@ listeners than added", [self class]);
} }
if (count == _listenerCount) { _listenerCount = MAX(_listenerCount - count, 0);
if (_listenerCount == 0) {
[self stopObserving]; [self stopObserving];
} }
_listenerCount -= count;
} }
@end @end