Skip to content

Commit

Permalink
Use RCTBlockGuard for callback JSI <-> ObjC
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Jul 14, 2021
1 parent f8150e7 commit 3b45b92
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions ios/React Utils/JSIUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#import <ReactCommon/CallInvoker.h>
#import <React/RCTBridge.h>
#import <ReactCommon/TurboModuleUtils.h>
#import <ReactCommon/RCTBlockGuard.h>

#import "../Frame Processor/Frame.h"
#import "../Frame Processor/FrameHostObject.h"

Expand Down Expand Up @@ -86,7 +88,7 @@
for (size_t i = 0; i < length; i++) {
// Insert kCFNull when it's `undefined` value to preserve the indices.
[result
addObject:convertJSIValueToObjCObject(runtime, array[i], jsInvoker) ?: (id)kCFNull];
addObject:convertJSIValueToObjCObject(runtime, array[i], jsInvoker) ?: (id)kCFNull];
}
return [result copy];
}
Expand All @@ -106,7 +108,7 @@
for (size_t i = 0; i < size; i++) {
// Insert kCFNull when it's `undefined` value to preserve the indices.
[result
addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker) ?: (id)kCFNull];
addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker) ?: (id)kCFNull];
}
return [result copy];
}
Expand Down Expand Up @@ -165,6 +167,13 @@ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, s
RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime &runtime, const jsi::Function &value, std::shared_ptr<CallInvoker> jsInvoker)
{
auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker);
RCTBlockGuard *blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() {
auto strongWrapper = weakWrapper.lock();
if (strongWrapper) {
strongWrapper->destroy();
}
}];

BOOL __block wrapperWasCalled = NO;
RCTResponseSenderBlock callback = ^(NSArray *responses) {
if (wrapperWasCalled) {
Expand All @@ -176,7 +185,7 @@ RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime &runtime, const
return;
}

strongWrapper->jsInvoker().invokeAsync([weakWrapper, responses]() {
strongWrapper->jsInvoker().invokeAsync([weakWrapper, responses, blockGuard]() {
auto strongWrapper2 = weakWrapper.lock();
if (!strongWrapper2) {
return;
Expand All @@ -185,15 +194,13 @@ RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime &runtime, const
const jsi::Value* args = convertNSArrayToJSICStyleArray(strongWrapper2->runtime(), responses);
strongWrapper2->callback().call(strongWrapper2->runtime(), args, static_cast<size_t>(responses.count));
strongWrapper2->destroy();
delete[] args;

// Delete the CallbackWrapper when the block gets dealloced without being invoked.
(void)blockGuard;
});

wrapperWasCalled = YES;
};

if (RCTTurboModuleBlockCopyEnabled()) {
return [callback copy];
}

return callback;
return [callback copy];
}

0 comments on commit 3b45b92

Please sign in to comment.