@@ -61,6 +61,8 @@ @interface RCTCxxBridge : RCTBridge
61
61
62
62
static NSString *const RCTJSThreadName = @"com.facebook.react.JavaScript";
63
63
64
+ typedef void (^RCTPendingCall)();
65
+
64
66
using namespace facebook ::react;
65
67
66
68
/* *
@@ -157,7 +159,7 @@ @implementation RCTCxxBridge
157
159
BOOL _wasBatchActive;
158
160
BOOL _didInvalidate;
159
161
160
- NSMutableArray <dispatch_block_t > *_pendingCalls;
162
+ NSMutableArray <RCTPendingCall > *_pendingCalls;
161
163
std::atomic<NSInteger > _pendingCount;
162
164
163
165
// Native modules
@@ -972,7 +974,7 @@ - (void)logMessage:(NSString *)message level:(NSString *)level
972
974
973
975
#pragma mark - RCTBridge methods
974
976
975
- - (void )_runAfterLoad : (dispatch_block_t )block
977
+ - (void )_runAfterLoad : (RCTPendingCall )block
976
978
{
977
979
// Ordering here is tricky. Ideally, the C++ bridge would provide
978
980
// functionality to defer calls until after the app is loaded. Until that
@@ -1025,9 +1027,9 @@ - (void)_flushPendingCalls
1025
1027
// Phase B: _flushPendingCalls happens. Each block in _pendingCalls is
1026
1028
// executed, adding work to the queue, and _pendingCount is decremented.
1027
1029
// loading is set to NO.
1028
- NSArray *pendingCalls = _pendingCalls;
1030
+ NSArray <RCTPendingCall> *pendingCalls = _pendingCalls;
1029
1031
_pendingCalls = nil ;
1030
- for (dispatch_block_t call in pendingCalls) {
1032
+ for (RCTPendingCall call in pendingCalls) {
1031
1033
call ();
1032
1034
_pendingCount--;
1033
1035
}
@@ -1050,18 +1052,23 @@ - (void)enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray
1050
1052
RCT_PROFILE_BEGIN_EVENT (RCTProfileTagAlways, @" -[RCTCxxBridge enqueueJSCall:]" , nil );
1051
1053
1052
1054
RCTProfileBeginFlowEvent ();
1053
- [self _runAfterLoad: ^{
1055
+ __weak __typeof (self) weakSelf = self;
1056
+ [self _runAfterLoad: ^(){
1054
1057
RCTProfileEndFlowEvent ();
1058
+ __strong __typeof (weakSelf) strongSelf = weakSelf;
1059
+ if (!strongSelf) {
1060
+ return ;
1061
+ }
1055
1062
1056
- if (self ->_reactInstance ) {
1057
- self ->_reactInstance ->callJSFunction ([module UTF8String ], [method UTF8String ],
1058
- convertIdToFollyDynamic (args ?: @[]));
1063
+ if (strongSelf ->_reactInstance ) {
1064
+ strongSelf ->_reactInstance ->callJSFunction ([module UTF8String ], [method UTF8String ],
1065
+ convertIdToFollyDynamic (args ?: @[]));
1059
1066
1060
1067
// ensureOnJavaScriptThread may execute immediately, so use jsMessageThread, to make sure
1061
1068
// the block is invoked after callJSFunction
1062
1069
if (completion) {
1063
- if (self ->_jsMessageThread ) {
1064
- self ->_jsMessageThread ->runOnQueue (completion);
1070
+ if (strongSelf ->_jsMessageThread ) {
1071
+ strongSelf ->_jsMessageThread ->runOnQueue (completion);
1065
1072
} else {
1066
1073
RCTLogWarn (@" Can't invoke completion without messageThread" );
1067
1074
}
@@ -1086,11 +1093,16 @@ - (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args
1086
1093
*/
1087
1094
1088
1095
RCTProfileBeginFlowEvent ();
1089
- [self _runAfterLoad: ^{
1096
+ __weak __typeof (self) weakSelf = self;
1097
+ [self _runAfterLoad: ^(){
1090
1098
RCTProfileEndFlowEvent ();
1099
+ __strong __typeof (weakSelf) strongSelf = weakSelf;
1100
+ if (!strongSelf) {
1101
+ return ;
1102
+ }
1091
1103
1092
- if (self ->_reactInstance ) {
1093
- self ->_reactInstance ->callJSCallback ([cbID unsignedLongLongValue ], convertIdToFollyDynamic (args ?: @[]));
1104
+ if (strongSelf ->_reactInstance ) {
1105
+ strongSelf ->_reactInstance ->callJSCallback ([cbID unsignedLongLongValue ], convertIdToFollyDynamic (args ?: @[]));
1094
1106
}
1095
1107
}];
1096
1108
}
0 commit comments