Remove self capturing RCTCxxBridge->_pendingCalls

Differential Revision: D6387237

fbshipit-source-id: 3244bba439ba9fc38c5be09657cbdc787b9b4585
This commit is contained in:
Alex Dvornikov 2017-11-23 04:59:23 -08:00 committed by Facebook Github Bot
parent 7d969a05de
commit e7bd0f056b
1 changed files with 25 additions and 13 deletions

View File

@ -61,6 +61,8 @@
static NSString *const RCTJSThreadName = @"com.facebook.react.JavaScript";
typedef void (^RCTPendingCall)();
using namespace facebook::react;
/**
@ -157,7 +159,7 @@ struct RCTInstanceCallback : public InstanceCallback {
BOOL _wasBatchActive;
BOOL _didInvalidate;
NSMutableArray<dispatch_block_t> *_pendingCalls;
NSMutableArray<RCTPendingCall> *_pendingCalls;
std::atomic<NSInteger> _pendingCount;
// Native modules
@ -972,7 +974,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
#pragma mark - RCTBridge methods
- (void)_runAfterLoad:(dispatch_block_t)block
- (void)_runAfterLoad:(RCTPendingCall)block
{
// Ordering here is tricky. Ideally, the C++ bridge would provide
// functionality to defer calls until after the app is loaded. Until that
@ -1025,9 +1027,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
// Phase B: _flushPendingCalls happens. Each block in _pendingCalls is
// executed, adding work to the queue, and _pendingCount is decremented.
// loading is set to NO.
NSArray *pendingCalls = _pendingCalls;
NSArray<RCTPendingCall> *pendingCalls = _pendingCalls;
_pendingCalls = nil;
for (dispatch_block_t call in pendingCalls) {
for (RCTPendingCall call in pendingCalls) {
call();
_pendingCount--;
}
@ -1050,18 +1052,23 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge enqueueJSCall:]", nil);
RCTProfileBeginFlowEvent();
[self _runAfterLoad:^{
__weak __typeof(self) weakSelf = self;
[self _runAfterLoad:^(){
RCTProfileEndFlowEvent();
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (self->_reactInstance) {
self->_reactInstance->callJSFunction([module UTF8String], [method UTF8String],
convertIdToFollyDynamic(args ?: @[]));
if (strongSelf->_reactInstance) {
strongSelf->_reactInstance->callJSFunction([module UTF8String], [method UTF8String],
convertIdToFollyDynamic(args ?: @[]));
// ensureOnJavaScriptThread may execute immediately, so use jsMessageThread, to make sure
// the block is invoked after callJSFunction
if (completion) {
if (self->_jsMessageThread) {
self->_jsMessageThread->runOnQueue(completion);
if (strongSelf->_jsMessageThread) {
strongSelf->_jsMessageThread->runOnQueue(completion);
} else {
RCTLogWarn(@"Can't invoke completion without messageThread");
}
@ -1086,11 +1093,16 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
*/
RCTProfileBeginFlowEvent();
[self _runAfterLoad:^{
__weak __typeof(self) weakSelf = self;
[self _runAfterLoad:^(){
RCTProfileEndFlowEvent();
__strong __typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (self->_reactInstance) {
self->_reactInstance->callJSCallback([cbID unsignedLongLongValue], convertIdToFollyDynamic(args ?: @[]));
if (strongSelf->_reactInstance) {
strongSelf->_reactInstance->callJSCallback([cbID unsignedLongLongValue], convertIdToFollyDynamic(args ?: @[]));
}
}];
}