GCD

GCD 全称 Grand Central Dispatch

是苹果开发的一种支持并行操作的机制, 它的主要部件是一个FIFO队列和一个线程池,前者用来添加任务,后者用来执行任务。

GCD中的FIFO队列称为dispatch queue 它可以保证先进来的任务先得到执行(但不一定先执行结束) 通过个线程池的配合,dispatch queue分为以下两种情况:

Serial Dispatch Queue 线程池只提供一个线程用来执行任务,所以后一个任务必须等到前一个任务结束才可以开始。

Concurrent Dispatch Queue 线程池提供多个线程来执行任务,所以可以按序启动多个任务并发执行

1 Basic Management

我们可以通过dispatch_queue_create来创建队列,然后用dispatch_release释放

比如下面两端代码分别创建串行队列和并行对列

dispatch_queue_t serialQ = dispatch_queue_create(“eg.gcd.SerialQueue”,DISPATCH_QUEUE_SERAIL);

dispatch_async(serialQ,^{

  // code here

 });


dispatch_release(serialQ);


dispatch_queue_t concurrentQ = dispatch_queue_create(“eg.gcd.ConcurrentQueue”,DISPATCH_QUEUE_CONCURRNT);

dispatch_async(concurrentQ,^{

  // code here

});

dispatch_release(concurrentQ);


系统默认就有一个串行队列main_queue 和并行队列global_queue


dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);


dispatch_queue_t mainQ = dispatch_get_main_queue();


通常我们在global_queue中做一些long_running的任务,完成后在main_queue中更新UI,避免UI堵塞,无法响应用户操作

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)^{

  // long_running task

  dispatch_async(dispatch_get_main_queue(),^{

     // update UI

   });

});

上面提到的dispatch_async这个接口,用来提交block给指定queue进行异步执行。这个接口会在成功提交block后立即返回,然后继续执行下去。由于block是定义在栈上的,所以需要将其复制到堆上。


与之相对应的是dispatch_sync接口,提交block以供同步执行。这个接口等到block执行完毕才返回,所以不需要复制block。so,如果在调用该接口在当前的queue上指派任务,就会导致死锁

dispatch_queue_t exampleQueue = dispatch_queue_create(“com.example.unique.identifier”,NULL);

dispatch_sync(exampleQueue,^{

     dispatch_sync(exampleQueue,^{

          // 死锁

     });

});


2 Normal Control


dispatch_once   保证整个应用程序生命周期中某段代码只被执行一次 单例和

static dispatch_once_t onceToken;

dispatch_once(&onceToken,^{

});

 

线程安全的单例

+(Singleton *)sharedInstance

{

    static Singleton *_instance;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken,^{

        _instance = [[self alloc] init];

     });

    return _instance;

}


dispatch_after

有时候我们需要等待几秒后做个动画或者给个指示,这时候可以用dispatch_after这个函数

double delayInSeconds = 2.0;

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,delayINSeconds *NSEC_PER_SEC);

dispatch_after(popTime,dispatch_get_main_queue(),^(void){

   // 在main queue里面的操作

});


dispatch_set_target_queue

通过dispatch_set_target_queue函数可以设置一个dispatch queue 的优先级,或者指定一个dispatch source相应的事件处理提交到哪个queue上

dispatch_set_target_queue(serialQ,globalQ); 将并行serialQ放在并行队列globalQ中


dispatch_apply

执行某个代码片段若干次

dispatch_apply(10,globalQ,^(size_t index){

   // do sth. 10 times

});


dispatch_group

Dispatch Group机制允许我们监听一组任务是否完场

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,concurrentQ,blk0);

dispatch_group_async(group,concurrentQ,blk1);

dispatch_group_async(group,concurrentQ,blk2);

dispatch_group_notify(group,mainQ,^{

    //update UI

});

dispatch_release(group);


或者说同步地等待一段时间看是否结束

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,lull *NSEC_PER_SEC);

dispatch_group_wait(group,time);


dispatch_barrier_async

通过dispatch_barrier_async函数提交的任务会等它前面的任务执行结束才开始,然后它后面的任务必须等它完毕才能开始

dispatch_async(concurrentQ,blk0);

dispatch_async(concurrentQ,blk1);

dispatch_barrier_async(concurrentQ,blk_barrier);

dispatch_async(concurrentQ,blk2);


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值