1.GCD 延时执行:dispatch_after
2.GCD 快速迭代:dispatch_apply
3.GCD 栅栏方法:dispatch_barrier_async
4.GCD 代码只执行一次:
1.GCD 延时执行:dispatch_after
注意:这种方法只适用于大概2秒的时间,并不非常精确,这中方法是2秒之后把任务添加到主队列,执行时间和结束时间并不确定。
/** * 延时执行 dispatch_after */ - (void)after { NSLog(@"begin"); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 2秒后异步到主队列开始执行 NSLog(@"2秒后:%@",[NSThread currentThread]); }); NSLog(@"end"); }
2.GCD 快速迭代:dispatch_apply
一般我们会用for循环遍历,dispatch_apply会将指定的任务追加到指定的队列中,并等待全部队列执行结束。
如果是在串行队列中使用
dispatch_apply
,那么就和 for 循环一样,按顺序同步执行。可这样就体现不出快速迭代的意义了。我们可以利用并发队列进行异步执行。比如说遍历 0~5 这6个数字,for 循环的做法是每次取出一个元素,逐个遍历。
dispatch_apply
可以 在多个线程中同时(异步)遍历多个数字。无论是在串行队列,还是异步队列中,dispatch_apply 都会等待全部任务执行完毕
/** * 快速迭代方法 dispatch_apply */ - (void)apply { // dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_queue_t queue = dispatch_queue_create("hzw", DISPATCH_QUEUE_SERIAL); NSLog(@"begin"); dispatch_apply(5, queue, ^(size_t index) { NSLog(@"序列index:%zd-----线程:%@",index, [NSThread currentThread]); }); NSLog(@"end"); }
把上面创建线程queue的注释互换一下,在并发队列中异步执行任务,打印如下:
所以各个任务的执行时间长短不定,最后结束顺序也不定。执行任务所在的线程也不一定,但是end
在最后执行。这是因为dispatch_apply
函数会等待全部任务执行完毕。
3.GCD 栅栏方法:dispatch_barrier_async
有时候我们会有这样的需求我们需要执行ABCD等若干个任务,等ABCD全部完成后在执行E任务刷新界面或者其他操作,(ABCD任务执行顺序无要求,但要全部执行完,当然NSOperationQueue也很容易),刷新成功之后再执行FG操作,这时候用栅栏方法就派上很大用场了。
/** * 栅栏方法 dispatch_barrier_async */ - (void)barrier { // 在执行完栅栏前面的操作之后,才执行栅栏操作,最后再执行栅栏后边的操作 dispatch_queue_t queue = dispatch_queue_create("hzw", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ // 追加任务1 for (int i = 0; i < 2; ++i) { NSLog(@"任务1---%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ // 追加任务2 for (int i = 0; i < 2; ++i) { NSLog(@"任务2---%@",[NSThread currentThread]); } }); dispatch_barrier_async(queue, ^{ // 追加任务 barrier for (int i = 0; i < 2; ++i) { NSLog(@"栅栏任务---%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ // 追加任务3 for (int i = 0; i < 2; ++i) { NSLog(@"任务3---%@",[NSThread currentThread]); } }); }
4.GCD 代码只执行一次:dispatch_once
dispatch_once
函数能保证某段代码在程序运行过程中只被执行1次,并且即使在多线程的环境下,dispatch_once
也可以保证线程安全。
/** * 一次性代码(只执行一次)dispatch_once */ - (void)once { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //执行代码 }); }