From 6926854fde58eac736d793f5eb1b1fafb95c7bed Mon Sep 17 00:00:00 2001 From: Jia Miao <854569347@qq.com> Date: Sun, 24 Jul 2016 23:39:08 +0800 Subject: [PATCH 1/2] fixed the performselector method lead memory leak use nsInvocation replaced --- Routable/Routable.m | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Routable/Routable.m b/Routable/Routable.m index b8ae96e..c2596ca 100644 --- a/Routable/Routable.m +++ b/Routable/Routable.m @@ -403,15 +403,34 @@ - (UIViewController *)controllerForRouterParams:(RouterParams *)params { SEL CONTROLLER_SELECTOR = sel_registerName("initWithRouterParams:"); UIViewController *controller = nil; Class controllerClass = params.routerOptions.openClass; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if ([controllerClass respondsToSelector:CONTROLLER_CLASS_SELECTOR]) { - controller = [controllerClass performSelector:CONTROLLER_CLASS_SELECTOR withObject:[params controllerParams]]; + +/*** + Fix by SerilesJam + this place use performselector will be cause leak and will be UIViewController instance can't excute -(void)dealloc + method. We replace the new method + ***/ + + if ([controllerClass respondsToSelector:CONTROLLER_CLASS_SELECTOR]) { + NSMethodSignature *sig = [controllerClass methodSignatureForSelector:CONTROLLER_CLASS_SELECTOR]; + NSInvocation *invocatin = [NSInvocation invocationWithMethodSignature:sig]; + [invocatin setTarget:controllerClass]; + [invocatin setSelector:CONTROLLER_CLASS_SELECTOR]; + NSDictionary *paramsDic = [params controllerParams]; + [invocatin setArgument:¶msDic atIndex:2]; + [invocatin invoke]; + [invocatin getReturnValue: &controller]; } else if ([params.routerOptions.openClass instancesRespondToSelector:CONTROLLER_SELECTOR]) { - controller = [[params.routerOptions.openClass alloc] performSelector:CONTROLLER_SELECTOR withObject:[params controllerParams]]; + NSMethodSignature *sig = [controllerClass instanceMethodSignatureForSelector:CONTROLLER_SELECTOR]; + NSInvocation *invocatin = [NSInvocation invocationWithMethodSignature:sig]; + [invocatin setTarget:controllerClass]; + [invocatin setSelector:CONTROLLER_SELECTOR]; + NSDictionary *paramsDic = [params controllerParams]; + [invocatin setArgument:¶msDic atIndex:2]; + [invocatin invoke]; + [invocatin getReturnValue: &controller]; } -#pragma clang diagnostic pop + if (!controller) { if (_ignoresExceptions) { return controller; From c5f4feb2d7d50bd38c94892d1e2f498767402db8 Mon Sep 17 00:00:00 2001 From: Jia Miao <854569347@qq.com> Date: Mon, 25 Jul 2016 02:31:10 +0800 Subject: [PATCH 2/2] alter the return controller logic fix the bug --- .../xcshareddata/xcschemes/Routable.xcscheme | 19 ++++++++++++------- Routable/Routable.m | 5 +++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Routable.xcodeproj/xcshareddata/xcschemes/Routable.xcscheme b/Routable.xcodeproj/xcshareddata/xcschemes/Routable.xcscheme index 9a0977e..65c566b 100644 --- a/Routable.xcodeproj/xcshareddata/xcschemes/Routable.xcscheme +++ b/Routable.xcodeproj/xcshareddata/xcschemes/Routable.xcscheme @@ -23,17 +23,17 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -48,17 +48,21 @@ ReferencedContainer = "container:Routable.xcodeproj"> + + - + - +