Last active
May 3, 2018 09:27
-
-
Save zhangkn/aa1e1704963fbd4b7e6cd1dcf4ab07e5 to your computer and use it in GitHub Desktop.
友盟统计模块的例子,使用Swizzle;---在系统提供的方法上再扩充功能时(不能重写系统方法),就可以使用`Method Swizzling`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//可以用于日志记录和 Mock 测试。例如上报用户打开的界面所在VC的名称,就可以使用swizzling 统一处理 | |
void Swizzle(Class c, SEL orig, SEL new) { | |
Method origMethod = class_getInstanceMethod(c, orig); | |
Method newMethod = class_getInstanceMethod(c, new); | |
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))//给一个方法添加新的方法和实现;Adds a new method to a class with a given name and implementation. | |
//若返回Yes说明类中没有该方法,然后再使用 `class_replaceMethod()` 方法进行取代 | |
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));//取代了对于一个给定类的实现方法 | |
else | |
//YES if the method was added successfully, otherwise NO (for example, the class already contains a method implementation with that name). | |
method_exchangeImplementations(origMethod, newMethod);//交换两个类的实现方法 | |
} | |
//当类加载之后,会调用一个名为 load 的类函数 | |
+ (void)load{//不会碰到并发问题。 | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{//由于我们只打算混淆一次,因此我们需要使用 dispatch_once | |
Swizzle([UIViewController class], @selector(viewWillAppear:), @selector(autolog_viewWillAppear:)); | |
Swizzle([UIViewController class], @selector(viewWillDisappear:), @selector(autolog_viewWillDisAppear:)); | |
Swizzle([UIViewController class], @selector(presentViewController:animated:completion:), @selector(autoLog_presentViewController:animated:completion:)); | |
Swizzle([UIViewController class], @selector(dismissViewControllerAnimated:completion:), @selector(autoLog_dismissViewControllerAnimated:completion:)); | |
}); | |
} | |
-(void)autolog_viewWillDisAppear:(BOOL)animated{ | |
if (![self isKindOfClass:[UINavigationController class]] && ![self isKindOfClass:[UITabBarController class]] && ![self isKindOfClass:[xxx class]] && ![self isKindOfClass:[xx class]]) { | |
[MobClick endLogPageView:NSStringFromClass([self class])];//友盟统计模块 | |
} | |
[self autolog_viewWillDisAppear:animated];//看似会陷入递归调用, | |
//其实则不会,因为我们已经在`+ (void)load `方法中更换了`IMP`,他会调用`viewWillDisAppear:`方法,然后在后面添加我们需要添加的功能。 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment