1.什么是GCD
GCD 全程为 Grand Central Dispatch 是异步执行任务的技术之一
2.Dispatch Queue
2.1 Serial Dispatch Queue
FIFO 先进先出原则,等待现在执行中的任务处理结束,是串行线程
2.2ConcurrentQueue
并行线程
2.3 Dispatch Queue的种类
Main Dispatch Queue(主线程执行 串行队列)
Global Dispatch Queue (High Priority 并行队列 优先级最高)
Global Dispatch Queue (Default Priority 并行队列 优先级默认)
Global Dispatch Queue (Low Priority 并行队列 优先级低)
Global Dispatch Queue (Background Priority 并行队列 优先级后台)
2.4 dispatch_set_target_queue
当用dispatch_queue_create生成的dispatch queue需要改变执行优先级用到的函数
2.5 dispatch_after
延迟执行处理,需要注意的是,dispatch_after 并不是在指定时间后执行处理,而只是在指定时间追加处理到dispatch queue
2.6 dispatch_group
在单个线程中想要等线程结束之后执行结束处理,这时候我们需要用到dispatch group 代码如下
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, globalQueue, ^{
NSLog(@"block 1");
});
dispatch_group_async(group, globalQueue, ^{
NSLog(@"block 2");
});
dispatch_group_async(group, globalQueue, ^{
NSLog(@"block 3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"block finish");
});
输出打印 block 1 2 3执行顺序不定,但是finish一定是最后输出的
2.7 dispatch_barrier_async
在访问数据时,用serial queue 我们可以避免数据竞争的问题,但是如果为了高效的对数据库进行读写,我们需要引入concurrent dispatch queue,但是我们知道concurrent dispatch queue是并行线程,如果我们需要在读取的线程内添加写的线程,这时候就会引发读取与写入的不符合,或者因为非法访问导致异常结束,因此我们需要dispatch_barrier_async 看如下代码
__block int readValue1 = 1;
__block int readValue2 = 1;
dispatch_queue_t conCurrentQueue = dispatch_queue_create("con_current_queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(conCurrentQueue, ^{
NSLog(@"block1 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"block2 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"block3 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
dispatch_async(conCurrentQueue, ^{
readValue1 = 2;
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"block4 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"block5 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
dispatch_barrier_async(conCurrentQueue, ^{
readValue2 = 2;
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"block6 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"block7 readValue1=%d,readValue2=%d",readValue1,readValue2);
});
/*
block1 readValue1=1,readValue2=1
block2 readValue1=1,readValue2=1
block4 readValue1=2,readValue2=1
block3 readValue1=2,readValue2=1
block5 readValue1=2,readValue2=1
block6 readValue1=2,readValue2=2
block7 readValue1=2,readValue2=2
*/
看打印 我们知道dispatch_barrier_async 是等前面的线程执行完才去执行,相当于阻断并行线程的作用
2.7 dispatch_apply
dispatch_apply 是dispatch_sync和dispatch_group的关联API
2.8 dispatch_suspend /dispatch_resume
挂起某个线程和恢复某个线程
2.9 dispatch_semaphore
我们先看一段代码
NSMutableArray *array = [[NSMutableArray alloc]init];
for(int i=0;i<10000;i++){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[array addObject:[NSNumber numberWithInt:i]];
});
}
该代码由内存错误导致程序异常
dispatch_semaphore 使用计数来实现功能,当计数为0时等待,当计数为1或者大于1时,减去1而不等待
NSMutableArray *array = [[NSMutableArray alloc]init];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
for(int i=0;i<10000;i++){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//等待semaphore -1操作,相当于线程阻塞
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[array addObject:[NSNumber numberWithInt:i]];
//semaphore +1操作
dispatch_semaphore_signal(semaphore);
});
}