GCD使用

2016-10-08  本文已影响0人  暖光照

名词

异步,在新的线程中执行任务,具备开启新的线程的能力。

在 GCD 中,这些术语描述当一个函数相对于另一个任务完成,此任务是该函数要求 GCD 执行的。一个同步函数只在完成了它预定的任务后才返回(阻塞当前Queue,先执行传入的Queue)

一个异步函数,刚好相反,会立即返回,预定的任务会完成但不会等它完成。因此,一个异步函数不会阻塞当前线程去执行下一个函数。

GCD获取的队列

//得到运行在主线程的mainQueue
dispatch_queue_t mainQueue=dispatch_get_main_queue();

//得到全局队列(全局的并行队列)
dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//创建一个串行队列
dispatch_queue_t serialQueue=dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);

//创建一个并行队列
dispatch_queue_t concurrentQueue=dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);

GCD的使用

基本使用
//同步执行
dispatch_sync(queue, ^{
    // do something
});

//异步执行
dispatch_async(queue, ^{
    // do something
});

// 一次性执行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // do something
});

// 延迟2秒执行:
double seconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC);
dispatch_after(popTime, queue, ^(void){
    // do something
});
使用group
    // 创建group
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, queue, ^{
    //任务一
});
dispatch_group_async(group, queue, ^{
    //任务二
});
dispatch_group_notify(group, queue, ^{
    //任务都结束调用
});
单例
 + (Manager *)sharedManager
{
    static Manager *sharedManagerInstance = nil;
    static dispatch_once_t onct;
    dispatch_once(&onct, ^{
    sharedManagerInstance = [[self alloc] init];
    });
    return sharedManagerInstance;
}

串行并行队列与同步异步执行的各种组合

1、 异步函数 + 并行队列
可以新建线程,各线程也是并发执行的。
结论:在队列中的任务“在多个线程并发”执行
2、 同步函数+并发队列
因为是同步函数,所以不新建线程,只要是同步函数,就不会新建线程。
并发队列与否,并不影响同步函数的创建,因为本身就不能多创建线程,也就不存在并发。
结论:在队列中的任务“one by one”执行
3、异步函数+串行队列
这个搭配可以新建线程,但是因为是串行队列,所以实际上也只是开了一条新线程,做完一个,再做另一个。
结论:在队列中的任务“在新线程one by one”执行
4、同步函数+串行队列
这样既不会开新线程,也是串行执行的。
结论:在队列中的任务“one by one”执行

注意:

当串行queue中调用dispatch_sync传入的还是当前queue,会造成死锁。
例如:

 dispatch_async(serialQueue1, ^{
    //serialQueue1队列中调用dispatch_sync传入的还是serialQueue1.
    //dispatch_async创建的新线程会死锁
    dispatch_sync(serialQueue1, ^{
        NSLog(@"1554654-----%@",[NSThread currentThread]);
    });
});           

或:

  //主线程中调用会死锁
   dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"1-----%@",[NSThread currentThread]);
 });

原因:
dispatch_sync会阻塞当前queue等待传入的queue执行完返回才会继续。而传入的还是当前queue。需要执行的block被放到传入queue的队尾等待执行。而queue还在等待dispatch_sync函数返回。block永远不会执行,dispatch_sync永远不会返回,造成死锁

上一篇下一篇

猜你喜欢

热点阅读