[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.
This commit is contained in:
Tadeu Zagallo 2015-06-12 10:43:22 -07:00
parent 3ff6abb6d1
commit 696b31f1a4
1 changed files with 11 additions and 8 deletions

View File

@ -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