方法交换

2018-05-16  本文已影响0人  StartBoy

+(void)load

}

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);

}

}

看回第一块代码,红色的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

}

}

嗯,刚刚说到有部分Controller我是不发数据的,这里有两重判断,一个是加入到黑名单,另一个是 判断Controller的title属性是否为空

以上判断基本能满足我这个行为分析统计系统的需求,若还需要什么判断还可以继续加

以此 我只需要往工程里面添加这个Category,这个viewDidAppear就会被hook出来,可以为所欲为..


另外 需求中还提到 需要在应用启动的时候发送一次init消息

hook?可以,但我更倾向与利用category+NSNotification,因为系统中已经有 UIApplicationDidFinishLaunchingNotification

这种通知,直接用就可以

@implementation UIApplication (GBHTracer)

 + (void)load{

[super load];



static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{ //只执行一次就可以了

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(__gbh_tracer_applicationDidFinishLaunching:) name:UIApplicationDidFinishLaunchingNotification object:nil];

});

}

+ (void)__gbh_tracer_applicationDidFinishLaunching:(NSNotification 
   *)noti{

      //应用启动时为所欲为!

 }
上一篇下一篇

猜你喜欢

热点阅读