[ReactNative] Fix crash when reload during profile

Summary:
Fixes #1642

When reloading during profiling, the profile wouldn't unhook from the instance
being deallocated.
This commit is contained in:
Tadeu Zagallo 2015-07-07 18:23:58 -07:00
parent a251316a5f
commit 0ffb2d36eb
4 changed files with 31 additions and 4 deletions

View File

@ -106,6 +106,13 @@ id<RCTJavaScriptExecutor> RCTGetLatestExecutor(void)
*/
[self registerModules];
/**
* If currently profiling, hook into the current instance
*/
if (RCTProfileIsProfiling()) {
RCTProfileHookModules(self);
}
/**
* Start the application script
*/
@ -364,8 +371,13 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
}
moduleData.queue = nil;
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[_javaScriptExecutor executeBlockOnJavaScriptQueue:^{
if (RCTProfileIsProfiling()) {
RCTProfileUnhookModules(self);
}
[_jsDisplayLink invalidate];
_jsDisplayLink = nil;

View File

@ -103,6 +103,16 @@ RCT_EXTERN void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *
RCTProfileEndEvent([NSString stringWithFormat:@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd)], category, arguments); \
}
/**
* Hook into a bridge instance to log all bridge module's method calls
*/
RCT_EXTERN void RCTProfileHookModules(RCTBridge *);
/**
* Unhook from a given bridge instance's modules
*/
RCT_EXTERN void RCTProfileUnhookModules(RCTBridge *);
#else
#define RCTProfileBeginFlowEvent()
@ -125,4 +135,7 @@ RCT_EXTERN void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *
#define RCTProfileBlock(block, ...) block
#define RCTProfileHookModules(...)
#define RCTProfileUnhookModules(...)
#endif

View File

@ -144,14 +144,17 @@ static IMP RCTProfileMsgForward(NSObject *self, SEL selector)
return imp;
}
static void RCTProfileHookModules(RCTBridge *);
static void RCTProfileHookModules(RCTBridge *bridge)
void RCTProfileHookModules(RCTBridge *bridge)
{
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
[moduleData dispatchBlock:^{
Class moduleClass = moduleData.cls;
Class proxyClass = objc_allocateClassPair(moduleClass, RCTProfileProxyClassName(moduleClass), 0);
if (!proxyClass) {
return;
}
unsigned int methodCount;
Method *methods = class_copyMethodList(moduleClass, &methodCount);
for (NSUInteger i = 0; i < methodCount; i++) {
@ -185,7 +188,6 @@ static void RCTProfileHookModules(RCTBridge *bridge)
}
}
void RCTProfileUnhookModules(RCTBridge *);
void RCTProfileUnhookModules(RCTBridge *bridge)
{
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {

View File

@ -436,7 +436,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder)
*/
- (UIView *)reactSuperview
{
RCTAssert(self.superview != nil, @"put reactNavSuperviewLink back");
RCTAssert(!_bridge.isValid || self.superview != nil, @"put reactNavSuperviewLink back");
return self.superview ? self.superview : self.reactNavSuperviewLink;
}