1414@implementation RCTEventEmitter {
1515 NSInteger _listenerCount;
1616 BOOL _observationDisabled;
17+ // Set to YES when -setCallableJSModules: is called with a non-nil value.
18+ // _callableJSModules is weak and can return to nil after wiring (e.g. on
19+ // host teardown) while this instance lives on, so the current value of
20+ // _callableJSModules can't tell us whether we were ever set up correctly.
21+ // This flag can.
22+ BOOL _callableJSModulesWasInitialized;
1723}
1824
1925@synthesize callableJSModules = _callableJSModules;
@@ -40,15 +46,14 @@ - (instancetype)initWithDisabledObservation
4046
4147- (void )sendEventWithName : (NSString *)eventName body : (id )body
4248{
43- // Assert that subclasses of RCTEventEmitter does not have `@synthesize _callableJSModules`
44- // which would cause _callableJSModules in the parent RCTEventEmitter to be nil.
4549 RCTAssert (
46- _callableJSModules != nil ,
47- @" Error when sending event: %@ with body: %@ . "
50+ _callableJSModulesWasInitialized ,
51+ @" Error when sending event: %@ (listenerCount: %lld ) with body: %@ . "
4852 " RCTCallableJSModules is not set. This is probably because you've "
4953 " explicitly synthesized the RCTCallableJSModules in %@ , even though it's inherited "
5054 " from RCTEventEmitter." ,
5155 eventName,
56+ (long long )_listenerCount,
5257 body,
5358 [self class ]);
5459
@@ -62,15 +67,25 @@ - (void)sendEventWithName:(NSString *)eventName body:(id)body
6267
6368 BOOL shouldEmitEvent = (_observationDisabled || _listenerCount > 0 );
6469
65- if (shouldEmitEvent && _callableJSModules) {
66- [_callableJSModules invokeModule: @" RCTDeviceEventEmitter"
67- method: @" emit"
68- withArgs: body ? @[ eventName, body ] : @[ eventName ]];
70+ // _callableJSModules is weak, so read it exactly once into a strong local.
71+ RCTCallableJSModules *callableJSModules = _callableJSModules;
72+ if (shouldEmitEvent && callableJSModules) {
73+ [callableJSModules invokeModule: @" RCTDeviceEventEmitter"
74+ method: @" emit"
75+ withArgs: body ? @[ eventName, body ] : @[ eventName ]];
6976 } else {
7077 RCTLogWarn (@" Sending `%@ ` with no listeners registered." , eventName);
7178 }
7279}
7380
81+ - (void )setCallableJSModules : (RCTCallableJSModules *)callableJSModules
82+ {
83+ _callableJSModules = callableJSModules;
84+ if (callableJSModules != nil ) {
85+ _callableJSModulesWasInitialized = YES ;
86+ }
87+ }
88+
7489- (void )startObserving
7590{
7691 // Does nothing
0 commit comments