GCD 常见用法

1、延迟执行

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    // 1秒后异步执行这里的代码...

});

2、后台执行

 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

3、主线程执行

 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

4、并发执行迭代循环

//GCD提供了一个简化方法叫做dispatch_apply,当我们把这个方法放到并发队列中执行时,这个函数会调用单一block多次,并平行运算,然后等待所有运算结束。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(count, queue, ^(size_t i) {
   NSLog("%d",i);
});

5、挂起和恢复队列

//有时候,我们不想让队列中的某些任务马上执行,这时我们可以通过挂起操作来阻止一个队列中将要执行的任务。当需要挂起队列时,使用dispatch_suspend方法;恢复队列时,使用dispatch_resume方法。调用dispatch_suspend会增加队列挂起的引用计数,而调用dispatch_resume则会减少引用计数,当引用计数大于0时,队列会保持挂起状态。因此,这队列的挂起和恢复中,我们需要小心使用以避免引用计数计算错误的出现。
dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
//挂起队列
dispatch_suspend(myQueue);
//恢复队列
dispatch_resume(myQueue);

//执行挂起操作不会对已经开始执行的任务起作用,它仅仅只会阻止将要进行但是还未开始的任务。

6、信号量:在程序开发中,有时候我们不想使用异步方式,例如我们想要调用函数后立刻获取结果值的时候,然后进行后续的数据操作。 这个时候需要信号量来等待返回结果,然后等到结果返回,从而进行后续处理。

信号量的作用是控制多个任务对有限数量资源的访问。一个dispatch semaphore就像一个普通信号的例外。当资源可用时,获取dispatch semaphore的时间比获取传统的系统信号量要更少。这是因为GCD不调用这个特殊情况下的内核。唯一的一次需要在内核中调用的情况是,当资源不可用且系统需要在停止你的线程直到获取信号。举例来说更容易理解,如果你创建了一个有着两个资源的信号量,那同时最多只能有两个线程可以访问临界区。其他想使用资源的线程必须在FIFO队列里等待。
// 创建一个信号量
dispatch_semaphore_t fd_sema = dispatch_semaphore_create(0);
// 等待一个空闲的文件描述符
dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER);
fd = open("/etc/services", O_RDONLY);
// 当完成时,释放掉文件描述符
close(fd);
dispatch_semaphore_signal(fd_sema);

7、创建单例模式

+ (LYServiceInterface *) shareacWebService {
    static LYServiceInterface *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[LYServiceInterface alloc] init];
    });
    return sharedInstance;
}

8、倒计时

 __block NSInteger timeOut = 60;//倒计时时间
    dispatch_queue_t queue    = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer  = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1*NSEC_PER_SEC, 0);//每秒执行
    self.getCodeBtn.userInteractionEnabled = false;
    dispatch_source_set_event_handler(_timer, ^{
        if (timeOut <= 0) {
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //设置时间
                [self.getCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
                self.getCodeBtn.userInteractionEnabled = true;
            });
        } else {
            NSString  *strTime = [NSString stringWithFormat:@"%ld 秒",(long)timeOut];
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.getCodeBtn setTitle:strTime forState:UIControlStateNormal];
            });
            timeOut--;
        }
    });
    dispatch_resume(_timer);

Dispatch groups是阻塞线程直到一个或多个任务完成的一种方式。在那些需要等待任务完成才能执行某个处理的时候,你可以使用这个方法。Dispatch Group会在整个组的任务都完成时通知你,这些任务可以是同步的,也可以是异步的,即便在不同的队列也行。而且在整个组的任务都完成时,Dispatch Group可以用同步的或者异步的方式通知你。当group中所有的任务都完成时,GCD 提供了两种通知方式。

9、异步执行2个耗时操作,等2个异步操作都执行完毕,再回到主线程执行操作

dispatch_group_t group =  dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 执行1个耗时的异步操作

});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 执行1个耗时的异步操作

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    // 等前面的异步操作都执行完毕后,回到主线程...

});

10、dispatch_group_wait。它会阻塞当前线程,直到组里面所有的任务都完成或者等到某个超时发生。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
// 添加队列到组中
dispatch_group_async(group, queue, ^{
// 一些异步操作
});
//如果在所有任务完成前超时了,该函数会返回一个非零值。
//你可以对此返回值做条件判断以确定是否超出等待周期;
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// 不需要group后将做释放操作
dispatch_release(group);

猜你喜欢

转载自my.oschina.net/u/1763048/blog/848414
gcd