*于是App端在某些页面切换,交互操作的时候需要给统计系统发送一条消息在几十个Controller 的项目里,一个一个地加代码那完全是不可能的,维护起来也是吃力,但这里需要处理的是 Controller, 可以有以下方式实现上述需求
(1). 利用Objective-C 中的对象继承
- 继承 在面向对象开发中是非常常用的,像我们现在做的项目工程中都会有一个BaseViewController,
- 所有新建的ViewController都继承BaseViewController,通过往BaseViewController中添加一些公共方法\属性 可以被他们的子类所调用
- 这是统一我们工程中所有视图控制器样式的一个主要途径
(2). 利用Category 和Runtime实行方法hook
- hook方案有一个好处,就是可以避免代码入侵,做到更加广泛的通用性.通过swizzling我们可以将原method与自己加入的method相结合,即不需要在原有工程中加入代码,又能做到全局覆盖
- 既然用到hook方案,又要用runtime 的swizzling
- 首先 新建一个UIViewController 的category
- 实现swizzling代码
+ (void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 假如要打开controller的统计 ,则把下面这行代码打开
__gbh_tracer_swizzleMethod([self class], @selector(viewDidAppear:), @selector(__gbh_tracer_viewDidAppear:));
});
}
- 嗯,看到这里大家会发现 这里调用的是一个C的方法,然而这个C方法是怎么实现的呢?看下面
void __gbh_tracer_swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector){
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
- 这是一个标准的swizzling写法,当然了 github上面也有关于swizzling的开源库,用起来也顺手 这里就不多说
- 看回第一块代码,红色的viewDidAppear是即将被我hook的方法,__gbh_tracer_viewDidAppear 则是我需要实现的方法
- (void)__gbh_tracer_viewDidAppear:(BOOL)animated{
[self __gbh_tracer_viewDidAppear:animated]; //由于方法已经被交换,这里调用的实际上是viewDidAppear:方法
//设置不允许发送数据的Controller
NSArray *filter = @[@"UINavigationController",@"UITabBarController"];
NSString *className = NSStringFromClass(self.class);
if ([filter containsObject:className]) return ; //如果该Controller在不允许发送log的列表里,则不能继续往下走
if ([self.title isKindOfClass:[NSString class]] && self.title.length > 0){ //有标题的才符合我的要求
// 这里发送log
}
}
- 这是转载地址 http://www.cnblogs.com/n1ckyxu/p/6186850.html
- 感谢!!!