From 220e116dce15f2cd9c1a08a9e7ed9ce7e918ae14 Mon Sep 17 00:00:00 2001 From: Ben Hiller Date: Tue, 7 Apr 2015 21:42:11 -0700 Subject: [PATCH] [fbobjc] revert rFBOBJCdba3daf9a595f452d069f2a74a9a11f251999b2e --- React/Base/RCTBridge.m | 36 ++++++++-------------------- React/Base/RCTBridgeModule.h | 2 +- React/Base/RCTJavaScriptLoader.m | 2 +- React/Base/RCTRootView.m | 30 +++++++++++------------ React/Executors/RCTContextExecutor.m | 13 +++++----- React/Modules/RCTUIManager.m | 5 +++- React/Views/RCTViewManager.h | 2 +- 7 files changed, 38 insertions(+), 52 deletions(-) diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 714304140..aa2ef7ee9 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -610,6 +610,7 @@ static id _latestJSExecutor; selector:@selector(reload) name:RCTReloadNotification object:nil]; + ; } }]; } @@ -618,8 +619,6 @@ static id _latestJSExecutor; - (void)bindKeys { #if TARGET_IPHONE_SIMULATOR - __weak RCTBridge *weakSelf = self; - // Workaround around the first cmd+r not working: http://openradar.appspot.com/19613391 // You can register just the cmd key and do nothing. This will trigger the bug and cmd+r // will work like a charm! @@ -628,33 +627,27 @@ static id _latestJSExecutor; action:^(UIKeyCommand *command) { // Do nothing }]; + [[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"r" modifierFlags:UIKeyModifierCommand action:^(UIKeyCommand *command) { - [weakSelf reload]; + [self reload]; }]; [[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"n" modifierFlags:UIKeyModifierCommand action:^(UIKeyCommand *command) { - RCTBridge *strongSelf = weakSelf; - if (!strongSelf) { - return; - } - strongSelf->_executorClass = Nil; - [strongSelf reload]; + _executorClass = Nil; + [self reload]; }]; + [[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"d" modifierFlags:UIKeyModifierCommand action:^(UIKeyCommand *command) { - RCTBridge *strongSelf = weakSelf; - if (!strongSelf) { - return; - } - strongSelf->_executorClass = NSClassFromString(@"RCTWebSocketExecutor"); - if (!strongSelf->_executorClass) { + _executorClass = NSClassFromString(@"RCTWebSocketExecutor"); + if (!_executorClass) { RCTLogError(@"WebSocket debugger is not available. Did you forget to include RCTWebSocketExecutor?"); } - [strongSelf reload]; + [self reload]; }]; #endif } @@ -669,7 +662,7 @@ static id _latestJSExecutor; - (void)dealloc { - [self invalidate]; + RCTAssert(!self.valid, @"must call -invalidate before -dealloc"); } #pragma mark - RCTInvalidating @@ -681,15 +674,6 @@ static id _latestJSExecutor; - (void)invalidate { - if (!self.isValid && _modulesByID == nil) { - return; - } - - if (![NSThread isMainThread]) { - [self performSelectorOnMainThread:@selector(invalidate) withObject:nil waitUntilDone:YES]; - return; - } - [[NSNotificationCenter defaultCenter] removeObserver:self]; // Wait for queued methods to finish diff --git a/React/Base/RCTBridgeModule.h b/React/Base/RCTBridgeModule.h index 3afac6daa..2134dc2e5 100644 --- a/React/Base/RCTBridgeModule.h +++ b/React/Base/RCTBridgeModule.h @@ -31,7 +31,7 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response); * will be set automatically by the bridge when it initializes the module. * To implement this in your module, just add @synthesize bridge = _bridge; */ -@property (nonatomic, weak) RCTBridge *bridge; +@property (nonatomic, strong) RCTBridge *bridge; /** * The module name exposed to JS. If omitted, this will be inferred diff --git a/React/Base/RCTJavaScriptLoader.m b/React/Base/RCTJavaScriptLoader.m index 205fd79da..1d61946b9 100755 --- a/React/Base/RCTJavaScriptLoader.m +++ b/React/Base/RCTJavaScriptLoader.m @@ -24,7 +24,7 @@ */ @implementation RCTJavaScriptLoader { - __weak RCTBridge *_bridge; + RCTBridge *_bridge; } /** diff --git a/React/Base/RCTRootView.m b/React/Base/RCTRootView.m index 9743ad4b2..6c15e509c 100644 --- a/React/Base/RCTRootView.m +++ b/React/Base/RCTRootView.m @@ -92,6 +92,19 @@ NSString *const RCTReloadViewsNotification = @"RCTReloadViewsNotification"; - (void)setUp { if (!_registered) { + /** + * Every root view that is created must have a unique react tag. + * Numbering of these tags goes from 1, 11, 21, 31, etc + * + * NOTE: Since the bridge persists, the RootViews might be reused, so now + * the react tag is assigned every time we load new content. + */ + _contentView = [[UIView alloc] init]; + _contentView.reactTag = [_bridge.uiManager allocateRootTag]; + _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; + [_contentView addGestureRecognizer:_touchHandler]; + [self addSubview:_contentView]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reload) name:RCTReloadViewsNotification @@ -109,9 +122,9 @@ NSString *const RCTReloadViewsNotification = @"RCTReloadViewsNotification"; - (void)tearDown { - [[NSNotificationCenter defaultCenter] removeObserver:self]; if (_registered) { _registered = NO; + [[NSNotificationCenter defaultCenter] removeObserver:self]; [_contentView removeGestureRecognizer:_touchHandler]; [_contentView removeFromSuperview]; [_touchHandler invalidate]; @@ -161,19 +174,6 @@ NSString *const RCTReloadViewsNotification = @"RCTReloadViewsNotification"; { dispatch_async(dispatch_get_main_queue(), ^{ _registered = YES; - /** - * Every root view that is created must have a unique react tag. - * Numbering of these tags goes from 1, 11, 21, 31, etc - * - * NOTE: Since the bridge persists, the RootViews might be reused, so now - * the react tag is assigned every time we load new content. - */ - _contentView = [[UIView alloc] initWithFrame:self.bounds]; - _contentView.reactTag = [_bridge.uiManager allocateRootTag]; - _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; - [_contentView addGestureRecognizer:_touchHandler]; - [self addSubview:_contentView]; - NSString *moduleName = _moduleName ?: @""; NSDictionary *appParameters = @{ @"rootTag": _contentView.reactTag, @@ -197,7 +197,7 @@ NSString *const RCTReloadViewsNotification = @"RCTReloadViewsNotification"; - (void)setFrame:(CGRect)frame { [super setFrame:frame]; - _contentView.frame = (CGRect){CGPointZero, frame.size}; + _contentView.frame = self.bounds; } - (void)reload diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index bdd969ce4..6c424ec7f 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -167,13 +167,12 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError) - (void)invalidate { - if (self.isValid) { - if ([NSThread currentThread] != _javaScriptThread) { - [self performSelector:@selector(invalidate) onThread:_javaScriptThread withObject:nil waitUntilDone:NO]; - } else { - JSGlobalContextRelease(_context); - _context = NULL; - } + if ([NSThread currentThread] != _javaScriptThread) { + // Yes, block until done. If we're getting called right before dealloc, it's the only safe option. + [self performSelector:@selector(invalidate) onThread:_javaScriptThread withObject:nil waitUntilDone:YES]; + } else if (_context != NULL) { + JSGlobalContextRelease(_context); + _context = NULL; } } diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index ce0a5baa9..c21adc1d0 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -177,7 +177,7 @@ static UIViewAnimationCurve UIViewAnimationCurveFromRCTAnimationType(RCTAnimatio @implementation RCTUIManager { - __weak dispatch_queue_t _shadowQueue; + dispatch_queue_t _shadowQueue; // Root views are only mutated on the shadow queue NSMutableSet *_rootViewTags; @@ -319,6 +319,7 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName) // Register shadow view dispatch_async(_shadowQueue, ^{ + RCTShadowView *shadowView = [[RCTShadowView alloc] init]; shadowView.reactTag = reactTag; shadowView.frame = frame; @@ -933,9 +934,11 @@ static void RCTMeasureLayout(RCTShadowView *view, RCTResponseSenderBlock callback) { if (!view) { + RCTLogError(@"Attempting to measure view that does not exist"); return; } if (!ancestor) { + RCTLogError(@"Attempting to measure relative to ancestor that does not exist"); return; } CGRect result = [view measureLayoutRelativeToAncestor:ancestor]; diff --git a/React/Views/RCTViewManager.h b/React/Views/RCTViewManager.h index 14277c615..32babecc9 100644 --- a/React/Views/RCTViewManager.h +++ b/React/Views/RCTViewManager.h @@ -28,7 +28,7 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, RCTSparseArray *v * allowing the manager (or the views that it manages) to manipulate the view * hierarchy and send events back to the JS context. */ -@property (nonatomic, weak) RCTBridge *bridge; +@property (nonatomic, strong) RCTBridge *bridge; /** * The module name exposed to React JS. If omitted, this will be inferred