这几天在看iOS-gcd相关的书籍,做一个简单的总结
1): 队列
分为串行队列和并行队列: dispatch_queue_create("serialQueue",nil),这个方法总共有两个参数,第一个参数是这个队列的名称,第二个参数有两个值可以选择,分别是"DISPATCH_QUEUE_SERIAL","DISPATCH_QUEUE_CONCURRENT",前面一个表示是创建的队列是串行队列,后面一个表示是并行的队列,第二个参数传nil表示创建的也是串行队列。
2):同步和异步
dispatch_sync表示是同步的线程,dispatch_asyn表示的是开启的是异步的线程。将多个任务添加在一个并发的队列里面,多个任务会并发执行。这种并发也可以创建多个串行的队列,然后将多个任务分别放入各串行队列中,也可以达到并发的目的,但是会影响性能。
dispatch_after:
这个函数可以用来创建一个延时执行的任务。dispatch_after(time, dispatch_get_main_queue(), ^{});第一个参数是一个dispatch_time_t类型的参数,dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);表示从现在开始,加上3秒,即3秒钟之后,dispatch_after不是表示3秒之后才执行这个方法,而是执行这个方法后,3秒钟之后再执行添加在队列中的任务。
dispatch_group :
可以用来当并行队列里面所有的任务都处理完成后,再需要执行的任务,用法如下

执行结果如下:
主要意思就是说:将队列里面要执行的任务和一个group关联起来,notify第一个group即为要监视的group,当group里面所有的任务都执行完成后,notify方法里面的block才执行。也可以使用dispatch_group_wait函数来打到同样的效果,将最后的notify函数换成下面的,执行结果也如下,可以看到最后的AAAAA的输出是在111111之后的,说明这个方法是阻塞了当前的线程的。
dipatch_barrier_asyn:
当我们的并发队列里面有任务1,任务2,任务3的时候,我们想在任务1任务2全部执行完成任务3执行之前,添加一个任务4,这个使用上面的group能够处理。下面是使用barrier函数来处理,代码和运行结果如下
执行结果如下
通过结果可以看到,由于是并行队列,任务1和任务2的执行顺序是不定的,但是任务barrier确实是在任务1和任务2全部执行完成之后再执行的,任务3是在任务barrier之后执行的。根据这个思想,其实"上面使用group来让所有的任务都执行完成后再执行"的问题使用barrier函数也能达到同样的效果。
dispatch_apply:
这个函数有点类似于前面的dispatch_group_wait函数,也会阻塞线程。这个函数的意思是将要执行的block向queue中添加3次,但是完成是最后打印的,说明是阻塞了当前的线程,第一个参数是重复的次数。看代码和执行结果
dispatch_semaphore_t:
直接看代码吧,我来根据代码来解释,后面是执行的结果,dispatch_semaphore_wait当信号量大于0的时候,信号量-1,dispatch_semaphore_signal信号量+1;
执行结果如下
首先介绍一下,当信号量为0的时候,wait函数会根据设置的时间来阻塞线程,当信号量大于0的时候,就不会阻塞。dispatch_semaphore_create(0)创建了一个信号量对象,初始的信号量个数为0,所以当执行到wait函数 的时候,由于信号量为0,线程阻塞,不会执行下面的NSLog方法;再看异步的队列里面,先执行打印了1111,2222,最后通过singal函数将信号量加1,此时信号量为1,信号量大于0就会执行最后的打印。
我是这么理解的,执行到wait方法的时候,如果信号量大于1,信号量就会减-1,并且不会阻塞线程,当信号量为0的时候,就会阻塞,直到信号量大于0,就会执行后面的代码,singal会使信号量+1。看下面的代码以及打印
执行结果如下
开始的时候信号量为0,所以最下面的不会打印,看队列里面,执行了signal后,信号量为1,接下来的wait后面的会执行,并且信号量-1又变为了0,所以"开始执行2"永远不会打印。
dispatch_once:
在应用程序中只会执行一次,可以用来生成单利的对象,如下