Release模式下UIButton按钮不可以二次点击

原有, 写了UIControl的分类, 防止重复点击, 也是在网上copy了很多代码, 之前测试都是跑的Debug版的, 没有任何问题. 上线前跑了个Release版的自测一下, 发现神奇的一幕发生了. 所有UIButton的点击方法只可以实现一次, 不可以跑第二次.

请教了朋友,找了1个多小时, 在朋友的提示下, 问我你是不是有防重. 才想起来分类, 去看了看. 结果果然是这个问题.

第一种解决办法把分类里load方法交换注释掉, 一切ok.

第二种解决办法, 依旧保留方法交换,但是在分类里自定义方法里

//        [self performSelector:@selector(setEventUnavailable:) withObject:@(YES) afterDelay:self.emDuration];

修改为

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.emDuration*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                self.eventUnavailable = NO;

            }); 先把问题解决掉了. 后来朋友我们几个就开始讨论为什么会有这种问题. 感谢https://www.coderzhou.com/2017/11/12/%E4%B8%80%E6%AC%A1%E7%94%B1performSelector%E5%BC%95%E5%8F%91%E7%9A%84BUG/ 这个作者的无私奉献.  结合到自己的代码发现是因为Bool值self.eventUnavailable 导致的. performSelector:withObject:afterDelay 这个方法在release和debug下结果不一致

 

感兴趣的同学可以参考这篇http://blog.zats.io/2014/03/12/performSelector-withObject/ 在32和64环境编译下结果不一样的

另外附上我的垃圾防重点分类. 希望对跟我一样出问题的同学们有帮助. 代码还是自己写吧. 像我就是在网上找的防重点的方法, 网上基本都是这样写的. 出问题了还得自己解决

#import <UIKit/UIKit.h>

@interface UIControl (EMTimer)

// 重复点击间隔

@property (nonatomic, assign) NSTimeInterval emDuration;

@end

 

实现

#import "UIControl+EMTimerl.h"

#import <objc/runtime.h>

static char * const emDuration = "emDurationKey";

static char * const eventUnavailableKey = "eventUnavailableKey";

@interface UIControl ()

@property (nonatomic, assign) BOOL eventUnavailable;

@end

@implementation UIControl (EMTimer)

+ (void)load {

    Method method = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));

    Method qi_method = class_getInstanceMethod(self, @selector(qi_sendAction:to:forEvent:));

    method_exchangeImplementations(method, qi_method);

}

#pragma mark - Action functions

- (void)qi_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {

    if (self.eventUnavailable == NO) {

        self.eventUnavailable = YES;

        [self qi_sendAction:action to:target forEvent:event];

//        [self performSelector:@selector(setEventUnavailable:) withObject:@(YES) afterDelay:self.emDuration];

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.emDuration*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                self.eventUnavailable = NO;

            });

    }

}

#pragma mark - Setter & Getter functions

- (NSTimeInterval)emDuration {    

    return [objc_getAssociatedObject(self, emDuration) doubleValue];

}

- (void)setEmDuration:(NSTimeInterval)qi_eventInterval {

    objc_setAssociatedObject(self, emDuration, @(qi_eventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (BOOL)eventUnavailable {

    return [objc_getAssociatedObject(self, eventUnavailableKey) boolValue];

}

- (void)setEventUnavailable:(BOOL)eventUnavailable {    

    objc_setAssociatedObject(self, eventUnavailableKey, @(eventUnavailable), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

@end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值