线程是执行者,队列是等待执行的任务队列。程序员
GCD是程序员告诉队列中的任务经过什么方式,在哪一个或哪些队列执行。objective-c
对于主线程中的task queue,至关于加入到了main RunLoop的dispatch block并发
对于并发队列中的task,至关于加入到了子线程RunLoop的dispatch block中,若是子线程尚未RunLoop会自动建立。异步
串行队列:队列中的任务只会顺序执行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);
复制代码
全局队列:是系统的,直接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();
复制代码
dispatch_sync(_queue, ^() {
//...
}
复制代码
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
//不使用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]);
});
复制代码
比NSTimer更精准
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
//dispatch_time的第二个参数的单位是纳秒
#define NSEC_PER_SEC 1000000000ull //每秒的纳秒数
复制代码
两种方法,其中第二种方法只能中止单个任务,不能取消整个队列的任务。
只能取消未开始的任务。
利用外部变量
利用dispatch_block_create、dispatch_block_cancel
GCD是纯C语言的API 。
NSOperationQueue是基于GCD的OC的封装。
GCD只支持FIFO队列,NSOperationQueue能够从新设置优先级,最大并发数。
NSOperationQueue但是方便设置operation之间的依赖关系,GCD则须要不少代码。
NSOperationQueue支持KVO,便可以观察任务的执行状态,正在执行(isExecuted),是否结束(isFinished),是否取消(isCanceled)。
GCD更接近底层,而NSOperationQueue则更高级抽象。
GCD速度更快。
任务之间的依赖关系。GCD须要本身写更多的代码来实现,而NSOperationQueue已经内建了这些支持。