美文网首页
test--runtime

test--runtime

作者: 乂滥好人 | 来源:发表于2018-07-25 16:06 被阅读5次

    参考:
    https://www.jianshu.com/p/6ebda3cd8052
    https://www.cnblogs.com/nbhhcty66/p/7070478.html http://www.cocoachina.com/ios/20170228/18798.html

    1、快速定位当前显示控制器(注:无需import文件,方便接手老项目时快速找到控制器)

    //  UIViewController+Swizzling.h
    
    #import <UIKit/UIKit.h>
    
    @interface UIViewController (Swizzling)
    
    @end
    
    //
    //  UIViewController+Swizzling.m
    
    #import "UIViewController+Swizzling.h"
    #import <objc/runtime.h>
    
    @implementation UIViewController (Swizzling)
    
    + (void)load
    {
    #ifdef DEBUG
        // 自定义方法交换系统方法,打印控制器名称,快速定位当前控制器
        Method m1 = class_getInstanceMethod(self, @selector(viewWillAppear:));
        Method m2 = class_getInstanceMethod(self, @selector(logViewWillAppear:));
        method_exchangeImplementations(m1, m2);
    #endif
    }
    
    - (void)logViewWillAppear:(BOOL)animated
    {
        NSString *className = NSStringFromClass([self class]);
        // 过滤系统控制器
        if (![className hasPrefix:@"UI"]) {
            NSLog(@"【%@】即将显示",className);
        }
        // 不干扰原代码流程,代码结束后要让本该执行的代码继续执行
        [self logViewWillAppear:animated];
    }
    
    @end
    

    log(注:即使当前控制器已实现此方法,也会先调用上面自定义分类的自定义方法)

    2018-07-25 15:58:21.435558+0800 RuntimeDome[5626:242889] 【ViewController】即将显示
    2018-07-25 15:58:22.669172+0800 RuntimeDome[5626:242889] 【TestViewController】即将显示
    2018-07-25 15:58:22.669328+0800 RuntimeDome[5626:242889] TestViewController中实现了viewWillAppear方法
    

    2、控制器打点,统计控制器展示次数

    2.1、工具类

    //  StatisticalTool.h
    @interface StatisticalTool : NSObject
    + (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;
    @end
    
    
    // StatisticalTool.m
    @implementation StatisticalTool
    
    + (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector
    {
        Class class = cls;
        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);
        }
    }
    @end
    

    2.2、使用

    #import "UIViewController+Swizzling.h"
    #import "StatisticalTool.h"
    
    @implementation UIViewController (Swizzling)
    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            SEL originalSelector = @selector(viewWillAppear:);
            SEL swizzledSelector = @selector(swiz_viewWillAppear:);
            [WHookUtility swizzlingInClass:[self class] originalSelector:originalSelector swizzledSelector:swizzledSelector];
        });
    }
    
    /** 自定义方法,在此进行所有控制器数据统计 */
    - (void)swiz_viewWillAppear:(BOOL)animated
    {
        NSLog(@"在此进行所有控制器数据统计,完成控制器打点");
        // 不干扰原代码流程,代码结束后要让本该执行的代码继续执行
        [self swiz_viewWillAppear:animated];
    }
    @end
    
    log: 
    2018-07-25 16:53:21.611699+0800 RuntimeDome[6233:280367] 在此进行所有控制器数据统计,完成控制器打点
    

    3、Button间隔点击

    3.1、创建UIControl分类

    #import <UIKit/UIKit.h>
    
    @interface UIControl (userClick)
    /** 时间间隔 */
    @property (nonatomic, assign) NSTimeInterval durationTime;
    
    @end
    
    #import "UIControl+userClick.h"
    #import "WHookUtility.h"
    #import <objc/runtime.h>
    
    @implementation UIControl (userClick)
    
    static const char *ButtonDurationTime = "ButtonDurationTime";
    
    + (void)load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            SEL originalSelector = @selector(sendAction:to:forEvent:);
            SEL swizzledSelector = @selector(swiz_sendAction:to:forEvent:);
            [WHookUtility swizzlingInClass:[self class] originalSelector:originalSelector swizzledSelector:swizzledSelector];
        });
    }
    
    - (void)swiz_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
    {
        self.userInteractionEnabled = NO;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.durationTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.userInteractionEnabled = YES;
        });
    
        [self swiz_sendAction:action to:target forEvent:event];
    }
    
    #pragma mark - runtime关联属性对象
    - (NSTimeInterval)durationTime
    {
        NSNumber *number = objc_getAssociatedObject(self, &ButtonDurationTime);
        return number.doubleValue;
    }
    
    - (void)setDurationTime:(NSTimeInterval)durationTime
    {
        NSNumber *number = [NSNumber numberWithDouble:durationTime];
        objc_setAssociatedObject(self, &ButtonDurationTime, number, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    @end
    

    3.2、使用:

    ①、头文件
    #import "UIControl+userClick.h"
    
    ②、设置间隔时长
    button.durationTime = 3.f;
    

    相关文章

      网友评论

          本文标题:test--runtime

          本文链接:https://www.haomeiwen.com/subject/rbopmftx.html