前文回顾:
上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue;第二种是直接使用系统提供的标准Dispatch Queue :Main Dispatch Queue和Global Dispatch Queue,具体的实现方式请参照上篇博客《iOS多线程开发之GCD(上篇)》。
这篇博客主要讲解以下苹果提供的一些常用GCD和代码示例及其注意点。
- dispatch_set_target_queue
- dispatch_after
- dispatch_once / dispatch_apply
- Dispatch Group
- dispatch_barrier_sync
- dispatch_suspend / dispatch_resume
- Dispatch Semaphore
一、dispatch_set_target_queue
dispatch_set_target_queue中涉及的代码示例来源于网络
1、dispatch_set_target_queue 更改Dispatch Queue的执行优先级
dispatch_queue_create函数生成的DisPatch Queue不管是Serial DisPatch Queue还是Concurrent Dispatch Queue,执行的优先级都与默认优先级的Global Dispatch queue相同,如果需要变更生成的Dispatch Queue的执行优先级则需要使用dispatch_set_target_queue函数。
dispatch_queue_t serialQueue = dispatch_queue_create("com.beckwang.www",NULL); dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0); // 第一个参数为要变更优先级的queue,第二个参数是参照物,既将第一个queue的优先级和第二个queue的优先级设置一样。 dispatch_set_target_queue(serialQueue, globalQueue);
2、dispatch_set_target_queue作为执行阶层,修改队列的目标队列使多个serial queue在目标queue上一次只有一个执行
第一种情况:使用dispatch_set_target_queue(Dispatch Queue1, Dispatch Queue2)实现队列的动态调度管理
- (void)testTargetQueue2 { //创建一个串行队列queue1 dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL); //创建一个串行队列queue2 dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL); //使用dispatch_set_target_queue()实现队列的动态调度管理 dispatch_set_target_queue(queue1, queue2); /* 那么dispatchA上还未运行的block会在dispatchB上运行。这时如果暂停dispatchA运行: dispatch_suspend(dispatchA); 这时则只会暂停dispatchA上原来的block的执行,dispatchB的block则不受影响。而如果暂停dispatchB的运行,则会暂停dispatchA的运行。 dispatch队列不支持cancel(取消),没有实现dispatch_cancel()函数,不像NSOperationQueue,不得不说这是个小小的缺憾 */ dispatch_async(queue1, ^{ for (NSInteger i = 0; i < 10; i++) { NSLog(@"queue1:%@, %ld", [NSThread currentThread], i); [NSThread sleepForTimeInterval:0.5]; if (i == 5) { dispatch_suspend(queue2); } } }); dispatch_async(queue1, ^{ for (NSInteger i = 0; i < 100; i++) { NSLog(@"queue1:%@, %ld", [NSThread currentThread], i); } }); dispatch_async(queue2, ^{ for (NSInteger i = 0; i < 100; i++) { NSLog(@"queue2:%@, %ld", [NSThread currentThread], i); } }); }