swizzleMethod以及友盟统计

如何统计一个应用中页面的数据统计,通过swizzleMethod以及友盟统计设计一个分类可简单的实现:
我们通过swizzleMethod修改了UIViewController的@selector(viewWillAppear:)对应的函数指针,使其实现指向了我们自定义的CXX_viewWillAppear的实现.这样,当UIViewController及其子类的对象调用viewWillAppear时,我们可以调用我们自定义的CXX_viewWillAppear,调用到友盟的统计代码,实现代码的注入.
其实也可以理解成交换方法,利用runtime的method_exchangeImplementations交换方法也是可实现的.
如下为分类代码实现:

#import "UIViewController+UMStatistic.h"
#import "MobClick.h"
@implementation UIViewController (UMStatistic)
+(void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        swizzleMethod(class ,@selector(viewWillAppear:),@selector(CXX_viewWillAppear:));
        swizzleMethod(class, @selector(viewWillDisappear:), @selector(CXX_viewWillDisappear:));
        
    });
}

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

-(void)CXX_viewWillAppear:(BOOL)animated
{
    NSString * name = NSStringFromClass([self class]);
    if ([name hasPrefix:@"CXX"]) {
        [MobClick beginLogPageView:name];
    }
}

- (void)CXX_viewWillDisappear:(BOOL)animated
{
    NSString * name = NSStringFromClass([self class]);
    if ([name hasPrefix:@"CXX"]) {
        [MobClick endLogPageView:name];
    }
}
@end

你可能感兴趣的:(swizzleMethod以及友盟统计)