iOS runtime 相关实例

作者: 72行代码 | 来源:发表于2019-04-19 11:14 被阅读13次

避免按钮快速点击多次相应问题

  • 创建UIButton 分类
//
//  UIButton+time.h
//

#import <UIKit/UIKit.h>

@interface UIButton (time)

/* 防止button重复点击,设置间隔 */
@property (nonatomic, assign) NSTimeInterval acceptEventInterval;

@end
//
//  UIButton+time.m
//

#import "UIButton+time.h"
#import <objc/runtime.h>

@implementation UIButton (time)

static const char *UIButton_acceptEventInterval = "UIButton_acceptEventInterval";
static const char *UIButton_acceptEventTime = "UIButton_acceptEventTime";

// get方法 获取时间间隔
- (NSTimeInterval)acceptEventInterval{
    return [objc_getAssociatedObject(self, UIButton_acceptEventInterval) doubleValue];
}

// set方法 赋值时间间隔
- (void)setAcceptEventInterval:(NSTimeInterval)mm_acceptEventInterval{
    objc_setAssociatedObject(self, UIButton_acceptEventInterval, @(mm_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

// get方法 获取时间
- (NSTimeInterval)acceptEventTime{
    return [objc_getAssociatedObject(self, UIButton_acceptEventTime) doubleValue];
}

// set方法 赋值时间
- (void)setAcceptEventTime:(NSTimeInterval)mm_acceptEventTime{
    objc_setAssociatedObject(self, UIButton_acceptEventTime, @(mm_acceptEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

/**
 class_addMethod:如果发现方法已经存在,会失败返回,也可以用来做检查用,我们这里是为了避免源方法没有实现的情况;如果方法没有存在,我们则先尝试添加被替换的方法的实现
 1.如果返回成功:则说明被替换方法没有存在.也就是被替换的方法没有被实现,我们需要先把这个方法实现,然后再执行我们想要的效果,用我们自定义的方法去替换被替换的方法. 这里使用到的是'class_replaceMethod'这个方法. class_replaceMethod本身会尝试调用class_addMethod和method_setImplementation,所以直接调用class_replaceMethod就可以了)
 2.如果返回失败:则说明被替换方法已经存在.直接将两个方法的实现交换即
 */
//分类中重写load方法,实现方法的交换(只要能让其执行一次方法交换语句,load再合适不过了)
+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //获取这两个方法
        Method systemMethod = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
        SEL sysSEL = @selector(sendAction:to:forEvent:);
        
        Method myMethod = class_getInstanceMethod(self, @selector(mm_sendAction:to:forEvent:));
        SEL mySEL = @selector(mm_sendAction:to:forEvent:);
        
        //添加方法进去
        BOOL isAddMethod = class_addMethod(self, sysSEL, method_getImplementation(myMethod), method_getTypeEncoding(myMethod));
        //如果添加方法成功
        if (isAddMethod) {
            class_replaceMethod(self, mySEL, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
        }else{
            method_exchangeImplementations(systemMethod, myMethod);
        }
    });
    /*-----以上主要是实现两个方法的互换,load是gcd的只shareinstance,果断保证执行一次-------*/
}

- (void)mm_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
    if ([NSDate date].timeIntervalSince1970 - self.acceptEventTime < self.acceptEventInterval) {
        return;
    }
    
    if (self.acceptEventInterval > 0) {
        self.acceptEventTime = [NSDate date].timeIntervalSince1970;
    }
    
    [self mm_sendAction:action to:target forEvent:event];
}

@end

附:我的博客地址

相关文章

  • iOS runtime 相关实例

    避免按钮快速点击多次相应问题 创建UIButton 分类 附:我的博客地址

  • IOS面试考察(一):runtime相关问题

    @[TOC] 1. IOS面试考察(一):runtime相关问题 1.1 runtime相关问题 runtime是...

  • iOS运行时Runtime

    相关文档:Runtime-iOS运行时基础篇 相关文档:Runtime-iOS运行时应用篇

  • Runtime学习笔记记录

    文章目录 一 runtime原理 二 Runtime相关的头文件2-1 iOS 中 Runtime相关的头...

  • runtime

    runtime官方runtime中文 一、iOS 开发基础知ivars(实例变量)与@property(属性) O...

  • iOS知识点整理

    iOS知识点整理 持续更新中。。。 runtime相关 iOS 模块详解—「Runtime面试、工作」看我就 ? ...

  • iOS RunTime 详解

    本文讲述 iOS Runtime 相关的知识点,从下面几个方面探寻 iOS Runtime的实现机制。 Runti...

  • iOS Runtime实例

    如果读者学到了有用的东西,希望能前往App Store下载《微言(官方版)》支持一下笔者,谢谢!? 《微言(官方版...

  • iOS RunTime之四:实例及实现分析

    看看别人都在用runtime做什么? 实例001:iOS中利用 runtime 一键改变字体 知识点: 利用Met...

  • iOS runtime--获取类信息

    iOS runtime--获取类信息 在iOS中可以通过runtime获取一个类的相关信息:有哪些方法、有哪些协议...

网友评论

    本文标题:iOS runtime 相关实例

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