From 696b31f1a432239c5de7c4e1ab3fa3bce5de7600 Mon Sep 17 00:00:00 2001 From: Tadeu Zagallo Date: Fri, 12 Jun 2015 10:43:22 -0700 Subject: [PATCH] [ReactNative] Fix memory leak in RCTContextExecutor Summary: @public Remove extra `JSGlobalContextRetain` that was causing the context ref to leak + remove `self` reference from block and improve invalidation Test Plan: Run the UIExplorer, reload the app a few times, verify that the memory usage is not increasing. --- React/Executors/RCTContextExecutor.m | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index d17791c9a..07fd562c4 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -68,6 +68,8 @@ NSThread *_javaScriptThread; } +@synthesize valid = _valid; + RCT_EXPORT_MODULE() /** @@ -224,6 +226,7 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) @"Can't initialize RCTContextExecutor without a javaScriptThread"); if ((self = [super init])) { + _valid = YES; _javaScriptThread = javaScriptThread; __weak RCTContextExecutor *weakSelf = self; [self executeBlockOnJavaScriptQueue: ^{ @@ -248,12 +251,11 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) __weak RCTContextExecutor *weakSelf = self; [self executeBlockOnJavaScriptQueue:^{ RCTContextExecutor *strongSelf = weakSelf; - if (!strongSelf) { + if (!strongSelf.isValid) { return; } if (!strongSelf->_context) { JSGlobalContextRef ctx = JSGlobalContextCreate(NULL); - JSGlobalContextRetain(ctx); strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:ctx]; } [strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"]; @@ -263,7 +265,7 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) [strongSelf _addNativeHook:RCTConsoleProfileEnd withName:"consoleProfileEnd"]; for (NSString *event in @[RCTProfileDidStartProfiling, RCTProfileDidEndProfiling]) { - [[NSNotificationCenter defaultCenter] addObserver:self + [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(toggleProfilingFlag:) name:event object:nil]; @@ -297,13 +299,14 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) } -- (BOOL)isValid -{ - return _context.isValid; -} - - (void)invalidate { + if (!self.isValid) { + return; + } + + _valid = NO; + #if RCT_DEV [[NSNotificationCenter defaultCenter] removeObserver:self]; #endif