GCD、及与NSOperationQueue的对比

1 线程、队列、RunLoop

1.1 线程与队列

  1. 线程是执行者,队列是等待执行的任务队列。程序员

  2. GCD是程序员告诉队列中的任务经过什么方式,在哪一个或哪些队列执行。objective-c

1.2 GCD与RunLoop

  1. 对于主线程中的task queue,至关于加入到了main RunLoop的dispatch block并发

  2. 对于并发队列中的task,至关于加入到了子线程RunLoop的dispatch block中,若是子线程尚未RunLoop会自动建立。异步

2 queue

2.1 自定义队列

串行队列:队列中的任务只会顺序执行async

dispatch_queue_t q = dispatch_queue_create("...", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q = dispatch_queue_create("...", NULL);
复制代码

并行队列: 队列中的任务一般会并发执行oop

dispatch_queue_t q = dispatch_queue_create("......",DISPATCH_QUEUE_CONCURRENT);
复制代码

2.2 系统标准队列

全局队列:是系统的,直接GET。并行spa

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
复制代码

主队列:每个应用程序对应惟一主队列,直接GET。串行 主队列只会运行在主线程上,使用主队列更新UI。 主线程能够执行其余队列的任务。线程

dispatch_queue_t q = dispatch_get_main_queue();
复制代码

3 同步、异步,针对的是向前线程

dispatch_sync(_queue, ^() {
    //...
}
复制代码

4 dispatch_group

Case: 有a、b、c、d 4个异步请求,如何判断a、b、c、d都完成执行?若是须要a、b、c、d顺序执行,该如何实现?code

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, ^{ /*任务a */ });
dispatch_group_async(group, queue, ^{ /*任务b */ });
dispatch_group_async(group, queue, ^{ /*任务c */ });
dispatch_group_async(group, queue, ^{ /*任务d */ });

//先提交,再用notify或者wait
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
// 在a、b、c、d异步执行完成后,会回调这里
});

//dispatch_group_wait(_loggingGroup, DISPATCH_TIME_FOREVER);
复制代码

顺序执行,queue用串行队列。cdn

5 dispatch_barrier_async

  1. 在同一个queue(哪怕是并行队列)里面,执行顺序:barrier以前的任务、barrier任务、barrier以后的任务。
  2. 只在自定义队列上有效,在系统标准队列上,效果等同于dispatch_sync。
//不使用barrier时
dispatch_queue_t queue = dispatch_queue_create("queue_name", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务1-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务2-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务3-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务4-----%@", [NSThread currentThread]);
    });
复制代码

dispatch_queue_t queue = dispatch_queue_create("queue_name", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务1-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务2-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务3-----%@", [NSThread currentThread]);
    });

    dispatch_barrier_async(queue, ^{
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"----耗时任务4-----%@", [NSThread currentThread]);
    });

 dispatch_async(queue, ^{
        NSLog(@"----耗时任务5-----%@", [NSThread currentThread]);
    });
复制代码

6 dispatch_time

比NSTimer更精准

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));

//dispatch_time的第二个参数的单位是纳秒

#define NSEC_PER_SEC 1000000000ull //每秒的纳秒数

复制代码

7 任务取消

两种方法,其中第二种方法只能中止单个任务,不能取消整个队列的任务。

只能取消未开始的任务。

  1. 利用外部变量

  2. 利用dispatch_block_create、dispatch_block_cancel

8 对比NSOperationQueue

8.1 NSOperationQueue与GCD之间的关系

GCD是纯C语言的API 。

NSOperationQueue是基于GCD的OC的封装。

8.2 二者的不一样

  1. GCD只支持FIFO队列,NSOperationQueue能够从新设置优先级,最大并发数。

  2. NSOperationQueue但是方便设置operation之间的依赖关系,GCD则须要不少代码。

  3. NSOperationQueue支持KVO,便可以观察任务的执行状态,正在执行(isExecuted),是否结束(isFinished),是否取消(isCanceled)。

8.3 结论

  1. GCD更接近底层,而NSOperationQueue则更高级抽象。

  2. GCD速度更快。

  3. 任务之间的依赖关系。GCD须要本身写更多的代码来实现,而NSOperationQueue已经内建了这些支持。

相关文章
相关标签/搜索