参考:
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;
网友评论