Skip to content

Commit 2c3a5d3

Browse files
Adam Ernstfacebook-github-bot
authored andcommitted
RCTEventEmitter: minor fix to callableJSModule check
Summary: Guard against possibly deallocated RCTCallableJSModules. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D108361186
1 parent fb58fd8 commit 2c3a5d3

1 file changed

Lines changed: 23 additions & 8 deletions

File tree

packages/react-native/React/Modules/RCTEventEmitter.m

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
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

Comments
 (0)