[ReactNative] Fix crash when reload during profile (attempt #2)
Summary: Fixes #1642 When reloading during profiling, the profile wouldn't unhook from the instance being deallocated.
This commit is contained in:
parent
8dd1256c25
commit
49b55804b1
|
@ -106,6 +106,13 @@ id<RCTJavaScriptExecutor> RCTGetLatestExecutor(void)
|
||||||
*/
|
*/
|
||||||
[self registerModules];
|
[self registerModules];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If currently profiling, hook into the current instance
|
||||||
|
*/
|
||||||
|
if (RCTProfileIsProfiling()) {
|
||||||
|
RCTProfileHookModules(self);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the application script
|
* Start the application script
|
||||||
*/
|
*/
|
||||||
|
@ -361,6 +368,7 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
||||||
}
|
}
|
||||||
moduleData.queue = nil;
|
moduleData.queue = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
|
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
|
||||||
[_javaScriptExecutor executeBlockOnJavaScriptQueue:^{
|
[_javaScriptExecutor executeBlockOnJavaScriptQueue:^{
|
||||||
[_jsDisplayLink invalidate];
|
[_jsDisplayLink invalidate];
|
||||||
|
@ -368,11 +376,15 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
||||||
|
|
||||||
[_javaScriptExecutor invalidate];
|
[_javaScriptExecutor invalidate];
|
||||||
_javaScriptExecutor = nil;
|
_javaScriptExecutor = nil;
|
||||||
}];
|
|
||||||
|
|
||||||
|
if (RCTProfileIsProfiling()) {
|
||||||
|
RCTProfileUnhookModules(self);
|
||||||
|
}
|
||||||
_modules = nil;
|
_modules = nil;
|
||||||
_modulesByName = nil;
|
_modulesByName = nil;
|
||||||
_frameUpdateObservers = nil;
|
_frameUpdateObservers = nil;
|
||||||
|
|
||||||
|
}];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,16 @@ RCT_EXTERN void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *
|
||||||
RCTProfileEndEvent([NSString stringWithFormat:@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd)], category, arguments); \
|
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
|
#else
|
||||||
|
|
||||||
#define RCTProfileBeginFlowEvent()
|
#define RCTProfileBeginFlowEvent()
|
||||||
|
@ -125,4 +135,7 @@ RCT_EXTERN void RCTProfileImmediateEvent(NSString *, NSTimeInterval , NSString *
|
||||||
|
|
||||||
#define RCTProfileBlock(block, ...) block
|
#define RCTProfileBlock(block, ...) block
|
||||||
|
|
||||||
|
#define RCTProfileHookModules(...)
|
||||||
|
#define RCTProfileUnhookModules(...)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -124,6 +124,8 @@ static void RCTProfileForwardInvocation(NSObject *self, __unused SEL cmd, NSInvo
|
||||||
RCTProfileBeginEvent();
|
RCTProfileBeginEvent();
|
||||||
[invocation invoke];
|
[invocation invoke];
|
||||||
RCTProfileEndEvent(name, @"objc_call,modules,auto", nil);
|
RCTProfileEndEvent(name, @"objc_call,modules,auto", nil);
|
||||||
|
} else if ([self respondsToSelector:invocation.selector]) {
|
||||||
|
[invocation invoke];
|
||||||
} else {
|
} else {
|
||||||
// Use original selector to don't change error message
|
// Use original selector to don't change error message
|
||||||
[self doesNotRecognizeSelector:invocation.selector];
|
[self doesNotRecognizeSelector:invocation.selector];
|
||||||
|
@ -144,14 +146,17 @@ static IMP RCTProfileMsgForward(NSObject *self, SEL selector)
|
||||||
return imp;
|
return imp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RCTProfileHookModules(RCTBridge *);
|
void RCTProfileHookModules(RCTBridge *bridge)
|
||||||
static void RCTProfileHookModules(RCTBridge *bridge)
|
|
||||||
{
|
{
|
||||||
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
||||||
[moduleData dispatchBlock:^{
|
[moduleData dispatchBlock:^{
|
||||||
Class moduleClass = moduleData.cls;
|
Class moduleClass = moduleData.cls;
|
||||||
Class proxyClass = objc_allocateClassPair(moduleClass, RCTProfileProxyClassName(moduleClass), 0);
|
Class proxyClass = objc_allocateClassPair(moduleClass, RCTProfileProxyClassName(moduleClass), 0);
|
||||||
|
|
||||||
|
if (!proxyClass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int methodCount;
|
unsigned int methodCount;
|
||||||
Method *methods = class_copyMethodList(moduleClass, &methodCount);
|
Method *methods = class_copyMethodList(moduleClass, &methodCount);
|
||||||
for (NSUInteger i = 0; i < methodCount; i++) {
|
for (NSUInteger i = 0; i < methodCount; i++) {
|
||||||
|
@ -185,20 +190,17 @@ static void RCTProfileHookModules(RCTBridge *bridge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTProfileUnhookModules(RCTBridge *);
|
|
||||||
void RCTProfileUnhookModules(RCTBridge *bridge)
|
void RCTProfileUnhookModules(RCTBridge *bridge)
|
||||||
{
|
{
|
||||||
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
|
||||||
[moduleData dispatchBlock:^{
|
|
||||||
RCTProfileLock(
|
RCTProfileLock(
|
||||||
|
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
||||||
Class proxyClass = object_getClass(moduleData.instance);
|
Class proxyClass = object_getClass(moduleData.instance);
|
||||||
if (moduleData.cls != proxyClass) {
|
if (moduleData.cls != proxyClass) {
|
||||||
object_setClass(moduleData.instance, moduleData.cls);
|
object_setClass(moduleData.instance, moduleData.cls);
|
||||||
objc_disposeClassPair(proxyClass);
|
objc_disposeClassPair(proxyClass);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}];
|
|
||||||
};
|
};
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -436,7 +436,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder)
|
||||||
*/
|
*/
|
||||||
- (UIView *)reactSuperview
|
- (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;
|
return self.superview ? self.superview : self.reactNavSuperviewLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue