iOS 高效开发-----延时执行用GCD

早期咱们使用延时执行的方法都是用NSObject 类提供的,performSelector:系列的方法,具体有哪些咱们看一下数组

咱们通常让某个对象延时执行某个方法都会调用包含  afterDelay这个参数的方法,此参数即表明延时多长时间执行 ,可是这一系列的方法的参数都只接受继承自NSObject类得对象,也就是说若是咱们要向其中传入基本的数据类型,那就必须涉及到数据类型转换,这显然会增长开销,并且这一系列的方法最多也就能传如一个参数,若是咱们要传多个参数怎么办呢 ,若是想继续使用这个方法,那咱们就必须把多个参数写入数组或字典中去,而后把数组或字典对象传给这个方法,那么着就又会增长咱们插入数组或字典,解析数组或字典的代码 ,数据量达到必定状况的话,这个开销是可想而知的,并且咱们还要知道数组和字典中得每一个对象都表明什么,很麻烦;async

不过咱们能够用块来解决这一问题 ,GCD 为咱们提供了一个演示执行的块函数,其具体定义以下:ide

void dispatch_after ( dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block );函数

咱们在调用此方法的时候,系统也考虑的很周到,当咱们写入dispatch_after时,这个完整的函数就会呈现出来,咱们看一下spa

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
    });

调用很方便,若是咱们想把里面的内容放到主线程中去运行的话,也很方便,例如:线程

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [son study];
    });
});

 

还记得当时有一个问题,就是想给UIButton的点击事件加点料,让系统中的全部的按钮都禁止快速点击或者连击,当时问了看了好多博客,都没有好的解决方案,前篇一概的讨论或者建议,都是使用performSelector:afterDelay这种方法,可是这样的话,我还要实现另外一个方法 。后来是这么解决的呢 ,这里再次引用我以前写的内容,重写父类函数,而后使用GCD的dispatch_after 方法解决;code

具体实现以下:orm

//
//  CommonButton.h
//  CommonButton
//
//  Created by pk on 14/12/24.
//  Copyright (c) 2014年 pk. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface CommonButton : UIButton

@end

  

//
//  CommonButton.m
//  CommonButton
//
//  Created by pk on 14/12/24.
//  Copyright (c) 2014年 pk. All rights reserved.
//

#import "CommonButton.h"

@implementation CommonButton

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/


- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
    [super sendAction:action to:target forEvent:event];
    self.enabled = NO;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.enabled = YES;
    });
}

@end

  

这样的实现,很清楚,结构简明,使用简单,想使用此方法,只要将改一下类得继承就行;对象

 

总结:performSelector 系列方法所能处理的选择器太过于局限性了 ,选择器的返回值类型和参数的个数都会受到限制;blog

    而dispatch_after就没有这些问题,另外,若是想把任务放在另外一个线程上执行,最好不要用performSelector系列方法,而应该把任务封装到块里,而后调用GCD的相关方法来实现就行

相关文章
相关标签/搜索