@@ -173,22 +173,28 @@ static RCTResponseSenderBlock convertJSIFunctionToCallback(
173
173
const jsi::Function &value,
174
174
std::shared_ptr<react::JSCallInvoker> jsInvoker)
175
175
{
176
- __block auto wrapper = std::make_shared<react::CallbackWrapper>(value.getFunction (runtime), runtime, jsInvoker);
176
+ auto weakWrapper = react::CallbackWrapper::createWeak (value.getFunction (runtime), runtime, jsInvoker);
177
+ BOOL __block wrapperWasCalled = NO ;
177
178
return ^(NSArray *responses) {
178
- if (wrapper == nullptr ) {
179
+ if (wrapperWasCalled ) {
179
180
throw std::runtime_error (" callback arg cannot be called more than once" );
180
181
}
181
182
182
- std::shared_ptr<react::CallbackWrapper> rw = wrapper;
183
- wrapper->jsInvoker ().invokeAsync ([rw, responses]() {
184
- std::vector<jsi::Value> args = convertNSArrayToStdVector (rw->runtime (), responses);
185
- rw->callback ().call (rw->runtime (), (const jsi::Value *)args.data (), args.size ());
186
- });
183
+ auto strongWrapper = weakWrapper.lock ();
184
+ if (!strongWrapper) {
185
+ return ;
186
+ }
187
187
188
- // The callback is single-use, so force release it here.
189
- // Doing this also releases the jsi::jsi::Function early, since this block may not get released by ARC for a while,
190
- // because the method invocation isn't guarded with @autoreleasepool.
191
- wrapper = nullptr ;
188
+ strongWrapper->jsInvoker ().invokeAsync ([weakWrapper, responses]() {
189
+ auto strongWrapper2 = weakWrapper.lock ();
190
+ if (!strongWrapper2) {
191
+ return ;
192
+ }
193
+
194
+ std::vector<jsi::Value> args = convertNSArrayToStdVector (strongWrapper2->runtime (), responses);
195
+ strongWrapper2->callback ().call (strongWrapper2->runtime (), (const jsi::Value *)args.data (), args.size ());
196
+ strongWrapper2->destroy ();
197
+ });
192
198
};
193
199
}
194
200
@@ -222,13 +228,13 @@ static RCTResponseSenderBlock convertJSIFunctionToCallback(
222
228
return jsi::Value::undefined ();
223
229
}
224
230
225
- std::shared_ptr<CallbackWrapper> resolveWrapper =
226
- std::make_shared< react::CallbackWrapper> (args[0 ].getObject (rt).getFunction (rt), rt, jsInvoker);
227
- std::shared_ptr<CallbackWrapper> rejectWrapper =
228
- std::make_shared< react::CallbackWrapper> (args[1 ].getObject (rt).getFunction (rt), rt, jsInvoker);
231
+ auto weakResolveWrapper =
232
+ react::CallbackWrapper::createWeak (args[0 ].getObject (rt).getFunction (rt), rt, jsInvoker);
233
+ auto weakRejectWrapper =
234
+ react::CallbackWrapper::createWeak (args[1 ].getObject (rt).getFunction (rt), rt, jsInvoker);
229
235
230
- BOOL __block resolveWasCalled = NO ;
231
- BOOL __block rejectWasCalled = NO ;
236
+ __block BOOL resolveWasCalled = NO ;
237
+ __block BOOL rejectWasCalled = NO ;
232
238
233
239
RCTPromiseResolveBlock resolveBlock = ^(id result) {
234
240
if (rejectWasCalled) {
@@ -239,23 +245,25 @@ static RCTResponseSenderBlock convertJSIFunctionToCallback(
239
245
throw std::runtime_error (" Tried to resolve a promise more than once." );
240
246
}
241
247
242
- // In the case that ObjC runtime first invokes this block after
243
- // the TurboModuleManager was invalidated, we should do nothing.
244
- if (resolveWrapper-> isDestroyed () ) {
248
+ auto strongResolveWrapper = weakResolveWrapper. lock ();
249
+ auto strongRejectWrapper = weakRejectWrapper. lock ();
250
+ if (!strongResolveWrapper || !strongRejectWrapper ) {
245
251
return ;
246
252
}
247
253
248
- resolveWrapper->jsInvoker ().invokeAsync ([resolveWrapper, rejectWrapper, result]() {
249
- if (resolveWrapper->isDestroyed ()) {
254
+ strongResolveWrapper->jsInvoker ().invokeAsync ([weakResolveWrapper, weakRejectWrapper, result]() {
255
+ auto strongResolveWrapper2 = weakResolveWrapper.lock ();
256
+ auto strongRejectWrapper2 = weakRejectWrapper.lock ();
257
+ if (!strongResolveWrapper2 || !strongRejectWrapper2) {
250
258
return ;
251
259
}
252
260
253
- jsi::Runtime &rt = resolveWrapper ->runtime ();
261
+ jsi::Runtime &rt = strongResolveWrapper2 ->runtime ();
254
262
jsi::Value arg = convertObjCObjectToJSIValue (rt, result);
255
- resolveWrapper ->callback ().call (rt, arg);
263
+ strongResolveWrapper2 ->callback ().call (rt, arg);
256
264
257
- resolveWrapper ->destroy ();
258
- rejectWrapper ->destroy ();
265
+ strongResolveWrapper2 ->destroy ();
266
+ strongRejectWrapper2 ->destroy ();
259
267
});
260
268
261
269
resolveWasCalled = YES ;
@@ -270,24 +278,26 @@ static RCTResponseSenderBlock convertJSIFunctionToCallback(
270
278
throw std::runtime_error (" Tried to reject a promise more than once." );
271
279
}
272
280
273
- // In the case that ObjC runtime first invokes this block after
274
- // the TurboModuleManager was invalidated, we should do nothing.
275
- if (rejectWrapper-> isDestroyed () ) {
281
+ auto strongResolveWrapper = weakResolveWrapper. lock ();
282
+ auto strongRejectWrapper = weakRejectWrapper. lock ();
283
+ if (!strongResolveWrapper || !strongRejectWrapper ) {
276
284
return ;
277
285
}
278
286
279
287
NSDictionary *jsError = RCTJSErrorFromCodeMessageAndNSError (code, message, error);
280
- rejectWrapper->jsInvoker ().invokeAsync ([rejectWrapper, resolveWrapper, jsError]() {
281
- if (rejectWrapper->isDestroyed ()) {
288
+ strongRejectWrapper->jsInvoker ().invokeAsync ([weakResolveWrapper, weakRejectWrapper, jsError]() {
289
+ auto strongResolveWrapper2 = weakResolveWrapper.lock ();
290
+ auto strongRejectWrapper2 = weakRejectWrapper.lock ();
291
+ if (!strongResolveWrapper2 || !strongRejectWrapper2) {
282
292
return ;
283
293
}
284
294
285
- jsi::Runtime &rt = rejectWrapper ->runtime ();
295
+ jsi::Runtime &rt = strongRejectWrapper2 ->runtime ();
286
296
jsi::Value arg = convertNSDictionaryToJSIObject (rt, jsError);
287
- rejectWrapper ->callback ().call (rt, arg);
297
+ strongRejectWrapper2 ->callback ().call (rt, arg);
288
298
289
- rejectWrapper ->destroy ();
290
- resolveWrapper ->destroy ();
299
+ strongResolveWrapper2 ->destroy ();
300
+ strongRejectWrapper2 ->destroy ();
291
301
});
292
302
293
303
rejectWasCalled = YES ;
0 commit comments