GCD全称:Grand Central Dispatch,是Apple开发的一套底层多核编程的API,它主要用于优化应用程序以支持多核处理器,它是一个在线程池模式的基础上执行的并行任务。GCD可以让我们不用直接和线程打交道,而是通过把任务分配给dispatch queues(调度队列),然后让这些queues去执行task(任务)
一、定义队列
1.串行队列:dispatch_get_main_queue()
例:dispatch_queue_t mainQueue = dispatch_get_main_queue();
//串行 queue 每次只能执行一个任务,可以使用它来代替锁,保护共享资源或可变的数据结构,串行queue确保任务按可预测的顺序执行(这是比锁好的地方)
//多用于处理UI
2.并行队列:dispatch_get_global_queue(优先级,扩展)
/*
参数1:优先级 High、Default、Low、Background。
参数2:预保留参数,暂时不明其作用。写“0”
*/
例:dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//并行队列,任务同时执行,多用于处理数据
3.用户队列(自定义队列):dispatch_queue_create(队列标签, 串行/并行)
/*
参数1:标签(标识符)要保证其为全局唯一,Apple官方就推荐使用反DNS的格式来命名,这纯是为了debug,这些名字会在崩溃日志中被显示出来,也可以被调试器调用,这在调试中会很有用
参数2:(DISPATCH_QUEUE_CONCURRENT)并行/(DISPATCH_QUEUE_SERIAL)串行
*/
例:dispatch_queue_tmyQueue = dispatch_queue_create("com.test.myQueueTag",DISPATCH_QUEUE_CONCURRENT);
//使用DISPATCH_QUEUE_CONCURRENT 就相当于是dispatch_get_global_queue 串行也同理
4.成组队列:dispatch_group_t group = dispatch_group_create();
用法:多用于并行队列,多任务时
//在dispatch_queue中当所有的任务执行完成后想做其他操作
//在串行队列中(一般不需要用到group),可以把该操作放到最后一个任务执行完成后继续
//并行队列中,就用group的notify, dispatch_notify()是group结束的点
示例代码:
{ dispatch_group_async(group,globalQueue, ^{ [selfdosomething:@"A"]; }); dispatch_group_async(group,globalQueue, ^{ [selfdosomething:@"B"]; }); dispatch_group_notify(group,globalQueue, ^{ [selfdosomething:@"我最后执行"]; }); dispatch_group_async(group, globalQueue, ^{ [self dosomething:@"C"]; }); }//A,B,C并行执行,最后再执行notify
二、异步调度和同步调度(提交任务)
1.异步调度 dispatch_async : dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
//把一个任务添加到某queue后就马上离开,而不管任务在那个queue里的执行状态(立即执行)
示例代码:
模板: dispatch_async(globalQueue, ^{ //请求数据(分线程) dispatch_async(mainQueue, ^{ //UI操作(主线程) }); });
2.同步调度 dispatch_sync : dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
//把一个任务添加到某queue后,等这个任务完成,调用线程才继续执行.(等前面的任务执行完)
三、GCD的更多用法
例:
{ staticdispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只调用一次"); }); }
{ dispatch_apply(4,globalQueue, ^(size_t t) { NSLog(@"%ld",t); }); }
3.dispatch_after(延迟操作)
例:
dispatch_after(<#dispatch_time_t when#>, <#dispatch_queue_t queue#>, <#^(void)block#>) { doubledelayInSeconds =2.0; dispatch_time_t popTime =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ NSLog(@"2秒后执行"); }); }
4.dispatch_barrier_async(并行队列中,可充当分割线)
例:
{ dispatch_queue_t myQueue =dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT); dispatch_async(myQueue, ^{ [selfdosomething:@"A"]; }); dispatch_async(myQueue, ^{ [selfdosomething:@"B"]; }); //分割 dispatch_barrier_async(myQueue, ^{ [selfdosomething:@"C"]; }); dispatch_async(myQueue, ^{ [selfdosomething:@"D"]; }); dispatch_async(myQueue, ^{ [selfdosomething:@"E"]; }); }