Runtime打印操作页面的项目类名,方便新人开发维护项目

在进入一个新公司时候,接触新的项目。在修改一些界面,而不知这个页面具体是工程中哪个类实现。而必须一个个类页面慢慢的寻找。其实我们可以直接使用RunTime的方法拦截和替换方法来监听页面WillAppear方法的实现,打印出此类的文件名,而不影响类中原有的方法实现。

LogClassName.gif

创建一个UIViewController的分类,实现代码后,直接丢入想要的查看的APP项目中,无需#import操作,方便快捷。


#import "UIViewController+LogClassName.h"

#import 

@implementation UIViewController (LogClassName)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class targetClass = [self class];
        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(swizzled_viewWillAppear:);
        swizzleMethod(targetClass, originalSelector, swizzledSelector);
    });
}

void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    IMP swizzledImp = method_getImplementation(swizzledMethod);
    char *swizzledTypes = (char *)method_getTypeEncoding(swizzledMethod);
    
    IMP originalImp = method_getImplementation(originalMethod);
    
    char *originalTypes = (char *)method_getTypeEncoding(originalMethod);
    BOOL success = class_addMethod(class, originalSelector, swizzledImp, swizzledTypes);
    if (success) {
        class_replaceMethod(class, swizzledSelector, originalImp, originalTypes);
    }else {
        // 添加失败,表明已经有这个方法,直接交换
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

- (void)swizzled_viewWillAppear:(BOOL)animation {
    [self swizzled_viewWillAppear:animation]; 
    NSLog(@"\n--------------------------------\n\n<----------------- 此类的名字是( %@ ) ----------------->\n\n--------------------------------\n", NSStringFromClass([self class]));
}


@end

+(void)load{} 方法只要文件存在项目中,方法会在加载类的时候就被调用,也就是 ios 应用启动的时候,就会加载所有的类,就会调用每个类的 + load 方法。

dispatch_once保证方法替换只执行一次

class_addMethod:如果发现方法已经存在,会失败返回,也可以用来做检查用,我们这里是为了避免源方法没有实现的情况;如果方法没有存在,我们则先尝试添加被替换的方法的实现:如果返回成功,说明被替换方法没有存在。被替换的方法没有被实现,我们需要先把这个方法实现,然后再执行我们想要的效果,用我们自定义的方法去替换被替换的方法。
如果返回失败:则说明被替换方法已经存在.直接将两个方法的实现交换即

class_replaceMethod这个方法.class_replaceMethod本身会尝试调用class_addMethodmethod_setImplementation,所以直接调用class_replaceMethod就可以了)


此方式也可以作为数据埋点的使用,只需要把你想要监听的系统方法替换在此类进行一次实现,当用户点击时候就可以进行数据统计。

你可能感兴趣的:(Runtime打印操作页面的项目类名,方便新人开发维护项目)