|
//A Quick Way Of Knowing Which View Controller You Are Pushing Into |
|
//I find it extremely useful when debugging other team members' (unfamiliar) code |
|
//Usage: Drop the snippet into a blank .m file. It'll NSLog when you are pushing a view controller. |
|
#import <Foundation/Foundation.h> |
|
#import <objc/runtime.h> |
|
#import <objc/message.h> |
|
|
|
typedef void(^Block_IMP_pushViewController_animated)(__unsafe_unretained id _self, __unsafe_unretained id arg1, BOOL arg2); |
|
|
|
static BOOL replaceMethodWithBlock(Class c, SEL origSEL, SEL newSEL, id block) { |
|
if ([c instancesRespondToSelector:newSEL]) { |
|
return YES; |
|
} |
|
Method origMethod = class_getInstanceMethod(c, origSEL); |
|
IMP impl = imp_implementationWithBlock(block); |
|
if (!class_addMethod(c, newSEL, impl, method_getTypeEncoding(origMethod))) { |
|
return NO; |
|
}else { |
|
Method newMethod = class_getInstanceMethod(c, newSEL); |
|
if (class_addMethod(c, origSEL, method_getImplementation(newMethod), method_getTypeEncoding(origMethod))) { |
|
class_replaceMethod(c, newSEL, method_getImplementation(origMethod), method_getTypeEncoding(newMethod)); |
|
}else { |
|
method_exchangeImplementations(origMethod, newMethod); |
|
} |
|
} |
|
return YES; |
|
} |
|
|
|
static Block_IMP_pushViewController_animated helper(SEL targetSelector) { |
|
return [^(__unsafe_unretained id _self, __unsafe_unretained id arg1, BOOL arg2) { |
|
((void ( *)(id, SEL, id, BOOL))objc_msgSend)(_self, targetSelector, arg1, arg2); |
|
NSLog(@"Push VC to : %@", arg1); |
|
} copy]; |
|
} |
|
|
|
static void swizzle() { |
|
SEL selector = @selector(pushViewController:animated:); |
|
NSString *selStr = NSStringFromSelector(selector); |
|
SEL newSelector = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"diwu_", selStr]); |
|
replaceMethodWithBlock([UINavigationController class], selector, newSelector, helper(newSelector)); |
|
} |
|
|
|
__attribute__((constructor)) static void DWUTransition(void) { |
|
@autoreleasepool { |
|
swizzle(); |
|
} |
|
} |