美文网首页iOS DeveloperiOS开发
performSelector withObject after

performSelector withObject after

作者: huanghy | 来源:发表于2018-07-06 16:10 被阅读58次

    今天在处理按钮连续点击重复请求的问题,进行延迟处理时,[self performSelector:@selector(setFjl_ignoreEvent:) withObject:@(NO) afterDelay:self.fjl_acceptEventInterval];。发现在执行到这行代码的时候,并没有调用 SEL 的方法。

    //解决按钮连续点击问题
    - (void)_fjl_sendAction:(SEL)selector to:(id)target forEvent:(UIEvent*)event{
        if (self.fjl_ignoreEvent) return;
        if (self.fjl_acceptEventInterval > 0) {
            self.fjl_ignoreEvent = YES;
            [self performSelector:@selector(setFjl_ignoreEvent:) withObject:@(NO) afterDelay:self.fjl_acceptEventInterval];
        }
        [self _fjl_sendAction:selector to:target forEvent:event];
    }
    

    此延迟方法没走,测试人员又着急测试,我变换了一种延迟方法,使用了dispatch_after,运行了一下,没有问题了。

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.fjl_acceptEventInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self setFjl_ignoreEvent:NO];
    });
    

    着实纳了闷,这两个方法到底有什么区别呢,经过我的一番努力,终于找到了答案。
    原来performSelector withObject afterDelay这个方法在子线程中,并不会调用SEL方法,而performSelect withObject 方法会直接调用。原因是:

    1. afterDelay 方式是使用当前线程的定时器在一定时间后调用SEL,NO AfterDelay方式是直接调用SEL.
    2. 主线程的runloop默认开启,子线程的runloop默认不开启,所以timer在子线程中是不会执行的,需要手动开启runloop。
    

    原因我们知道了,那么解决这个问题你是不是有了思路呢?

    1. 开启线程的定时器

       [self performSelector:@selector(setFjl_ignoreEvent:) withObject:@(NO) afterDelay:self.fjl_acceptEventInterval];
       [[NSRunLoop currentRunLoop] run];
      
    2. 使用dispatch_after来执行定时任务

       dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, self.fjl_acceptEventInterval*NSEC_PER_SEC);
       dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
           [self setFjl_ignoreEvent:NO];
       });
      
       或者
       
       //延时调用
       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.fjl_acceptEventInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
           [self setFjl_ignoreEvent:NO];
       });

    相关文章

      网友评论

      • 金玉游龙:不错,学习深入一点更好,便于理解原理

      本文标题:performSelector withObject after

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