GCD延迟执行
#pragma mark - GCD 延迟 /** * dispatch_after */ - (void)gcdDelay { NSLog(@"开始时间。。。。。。。%@",[NSDate date]); double delaySecond = 2.0; dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delaySecond*NSEC_PER_SEC); //得到当前的全局队列 dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void){ NSLog(@"延迟两秒执行......%@",[NSDate date]); }); }
C函数执行如下
/** * dispatch_after_f 执行的是一个纯C函数(processSomething) */ - (void)gcdDelay_t { NSLog(@"开始时间。。。。。。。%@",[NSDate date]); double delaySecond = 2.0; dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delaySecond*NSEC_PER_SEC); //得到当前的全局队列 dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //dispatch_after_f 执行的是一个纯C函数(processSomething) dispatch_after_f(delayInNanoSeconds, concurrentQueue, @"GCD", processSomething); } void processSomething(void *paramContext){ NSLog(@"%@",paramContext); }
2.GCD单例
- (void)gcdSingle { static dispatch_once_t onceTocken; void (^executedOnlyOnce)(void) = ^{ static NSUInteger numberOfEntries = 0; numberOfEntries++; NSLog(@"Executed %lu time(s)", (unsigned long)numberOfEntries); }; dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_once(&onceTocken, ^(void){ dispatch_async(concurrentQueue, executedOnlyOnce); }); dispatch_once(&onceTocken, ^(void){ dispatch_async(concurrentQueue, executedOnlyOnce); }); }
可以发现,输出只有一行,虽然我们调用了2次,因为我们传入的dispatch_once_t是相同的,编译器只执行一次。
3.GCD 队列调度
/** * 问题:我对每个任务用的是方法dispatch_group_async,是异步的啊。为什么顺序却不变呢? * 解答:因为他们都是分配给同一个队列dispatch_get_main_queue() 中的!在一个队列中是串行的啊。所以,还是按照顺序来。 */ - (void)gcdGroup { // 创建一个调度组 dispatch_group_t taskGroup = dispatch_group_create(); // 创建队列 dispatch_queue_t mainQueue = dispatch_get_main_queue(); // 任务1 // 将Block添加到指定的调度组(taskGroup)中,并且该Block用指定的队列(mainQueue)执行。 dispatch_group_async(taskGroup, mainQueue, ^{ [self reloadTableView]; }); // 任务2 // 将Block添加到指定的调度组(taskGroup)中,并且该Block用指定的队列(mainQueue)执行。 dispatch_group_async(taskGroup, mainQueue, ^{ [self reloadScrollView]; }); // 任务3 // 将Block添加到指定的调度组(taskGroup)中,并且该Block用指定的队列(mainQueue)执行。 dispatch_group_async(taskGroup, mainQueue, ^{ [self reloadImageView]; }); dispatch_group_notify(taskGroup, mainQueue, ^{ [[[UIAlertView alloc] initWithTitle:@"完成" message:@"所有调度完成" delegate:nil cancelButtonTitle:@"完成" otherButtonTitles:nil, nil] show]; }); } /** * 因为dispatch_group_async_f不像dispatch_group_t那样使用Block,可以访问当前类的变量。 * 由于 dispatch_group_async_f 接受 C 函数作为一个代码块来执行,所以,我们要执行reloadTableView方法,reloadScrollView方法,reloadImageView方法,必须有个当前类的引用!!!!! * 那么 C 函数必须有一 个引用到 Self,这个 Self 能够调用当前对象的实例方法 * */ /** * C函数的写法 */ - (void)gcdGroup_c { // 创建一个调度组 dispatch_group_t taskGroup = dispatch_group_create(); // 创建队列 dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_group_async_f(taskGroup, mainQueue, (__bridge void *)self, reloadAllComponents); } void reloadAllComponents(void *context) { ViewController *self = (__bridge ViewController *)context; [self reloadTableView]; [self reloadScrollView]; [self reloadImageView]; }
4.自定义队列调度
- (void)gcdCustomeGroup { dispatch_queue_t firstSerialQueue = dispatch_queue_create("com.sinoicity.gcd", NULL); dispatch_async(firstSerialQueue, ^{ NSUInteger counter = 0; for (counter = 0; counter < 5; counter++){ NSLog(@"First iteration, counter = %lu", (unsigned long)counter); } NSLog(@"Current thread = %@", [NSThread currentThread]); }); dispatch_async(firstSerialQueue, ^{ NSUInteger counter = 0; for (counter = 0; counter < 5; counter++){ NSLog(@"Second iteration, counter = %lu", (unsigned long)counter); } NSLog(@"Current thread = %@", [NSThread currentThread]); }); dispatch_async(firstSerialQueue, ^{ NSUInteger counter = 0; for (counter = 0; counter < 5; counter++){ NSLog(@"Third iteration, counter = %lu", (unsigned long)counter); } NSLog(@"Current thread = %@", [NSThread currentThread]); }); dispatch_queue_t mainQueue = dispatch_get_main_queue(); dispatch_async(mainQueue, ^{ NSLog(@"Main thread = %@", [NSThread mainThread]); }); }
注意:我们自定义的队列,往往不会在主队列中执行。而是单独分配一个线程来维护我们所定义的队列。