Permalink
Browse files

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 #11907

Differential Revision: D4738965

Pulled By: javache

fbshipit-source-id: cf175051be5b9c5de761d3dcd290560e1639b05e
  • Loading branch information...
fourlastor authored and facebook-github-bot committed Mar 20, 2017
1 parent f352aa1 commit 08c404d2939a3c2e75a514da1a7c03151fbb30e7
Showing with 4 additions and 4 deletions.
  1. +4 −4 React/Modules/RCTEventEmitter.m
@@ -78,21 +78,21 @@ - (void)dealloc
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)
{
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

0 comments on commit 08c404d

Please sign in to comment.