[ReactNative] Fix RootContentView release when the top-level bridge is held

Summary:
The RCTRootView creates a underlying RCTRootContentView that was deallocated when
the bridge modules were deallocated. That doesn't work when the bridge is held.

@public

Test Plan:
Launch Groups, put a breakpoint on `-[RCTRootContentView dealloc]`, enter and
leave a group page. It should be called now.
This commit is contained in:
Tadeu Zagallo 2015-05-12 07:44:38 -07:00 committed by Christopher Chedeau
parent a142ed50ff
commit 92d7324f15
3 changed files with 18 additions and 12 deletions

View File

@ -873,15 +873,19 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
return _eventDispatcher ?: _batchedBridge.eventDispatcher;
}
#define RCT_BRIDGE_WARN(...) \
#define RCT_INNER_BRIDGE_ONLY(...) \
- (void)__VA_ARGS__ \
{ \
RCTLogMustFix(@"Called method \"%@\" on top level bridge. This method should \
only be called from bridge instance in a bridge module", @(__func__)); \
}
RCT_BRIDGE_WARN(enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args)
RCT_BRIDGE_WARN(_invokeAndProcessModule:(NSString *)module method:(NSString *)method arguments:(NSArray *)args context:(NSNumber *)context)
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args
{
[self.batchedBridge enqueueJSCall:moduleDotMethod args:args];
}
RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSString *)method arguments:(NSArray *)args context:(NSNumber *)context)
@end
@ -1499,6 +1503,7 @@ RCT_BRIDGE_WARN(_invokeAndProcessModule:(NSString *)module method:(NSString *)me
@"module": method.moduleClassName,
@"method": method.JSMethodName,
@"selector": NSStringFromSelector(method.selector),
@"args": RCTJSONStringify(params ?: [NSNull null], NULL),
});
} forModule:@(moduleID)];

View File

@ -11,6 +11,7 @@
#import <objc/runtime.h>
#import "RCTAssert.h"
#import "RCTBridge.h"
#import "RCTContextExecutor.h"
#import "RCTEventDispatcher.h"
@ -53,6 +54,7 @@
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
{
RCTAssertMainThread();
RCTAssert(bridge, @"A bridge instance is required to create an RCTRootView");
RCTAssert(moduleName, @"A moduleName is required to create an RCTRootView");
@ -150,7 +152,7 @@ RCT_IMPORT_METHOD(ReactNative, unmountComponentAtNodeAndRemoveContainer)
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_contentView removeFromSuperview];
[_contentView invalidate];
}
@end
@ -212,13 +214,12 @@ RCT_IMPORT_METHOD(ReactNative, unmountComponentAtNodeAndRemoveContainer)
- (void)invalidate
{
self.userInteractionEnabled = NO;
}
- (void)dealloc
{
[_bridge enqueueJSCall:@"ReactNative.unmountComponentAtNodeAndRemoveContainer"
args:@[self.reactTag]];
if (self.isValid) {
self.userInteractionEnabled = NO;
[self removeFromSuperview];
[_bridge enqueueJSCall:@"ReactNative.unmountComponentAtNodeAndRemoveContainer"
args:@[self.reactTag]];
}
}
@end

View File

@ -281,7 +281,7 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewNa
dispatch_async(dispatch_get_main_queue(), ^{
for (NSNumber *rootViewTag in _rootViewTags) {
((UIView *)_viewRegistry[rootViewTag]).userInteractionEnabled = NO;
[_viewRegistry[rootViewTag] invalidate];
}
_rootViewTags = nil;