From f8be78379858c5d78eaf81e8a00d5e276481b72f Mon Sep 17 00:00:00 2001 From: Tadeu Zagallo Date: Wed, 9 Dec 2015 04:37:40 -0800 Subject: [PATCH] Document intentional retain cycle on RCTJavaScriptContext Summary: public More people wanted to understand the motivation behind the intentional retain cycle in `RCTJavaScriptContext`, add a small comment with some context. Reviewed By: jspahrsummers Differential Revision: D2738930 fb-gh-sync-id: d8c950778eb6bf3eaca627aabb6c98335d25d1fc --- React/Executors/RCTContextExecutor.m | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index 42b0a37e14..3c22398d5d 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -51,14 +51,22 @@ static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnable @implementation RCTJavaScriptContext { - RCTJavaScriptContext *_self; + RCTJavaScriptContext *_selfReference; } - (instancetype)initWithJSContext:(JSContext *)context { if ((self = [super init])) { _context = context; - _self = self; + + /** + * Explicitly introduce a retain cycle here - The RCTContextExecutor might + * be deallocated while there's still work enqueued in the JS thread, so + * we wouldn't be able kill the JSContext. Instead we create this retain + * cycle, and enqueue the -invalidate message in this object, it then + * releases the JSContext, breaks the cycle and stops the runloop. + */ + _selfReference = self; } return self; } @@ -79,7 +87,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init) { if (self.isValid) { _context = nil; - _self = nil; + _selfReference = nil; } }