1,dispatch_set_target_queue
dispatch_queue_t serialQueue = dispatch_queue_create("com.example", NULL);
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_set_target_queue(serialQueue, concurrentQueue);
想要改变serialQueue的执行优先级为后台执行,如上代码即可。
dispatch_set_target_queue的两个参数:
第一个参数:指定要变更优先级的队列
第二个参数:目标优先级队列。即要变成与此队列相同优先级的队列。
2,dispatch_group_notify
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
NSLog(@"f one");
});
dispatch_group_async(group, queue, ^{
NSLog(@"f two");
});
dispatch_group_async(group, queue, ^{
NSLog(@"f three");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"UI finish");
});
dispatch_group_notify三个参数:第一个:执行的group 第二个:group中得queue执行完之后要执行的queue 第三个:即为要执行的code
3,dispatch_barrier_async
dispatch_queue_t queue = dispatch_queue_create("com.example", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"reading one");
});
dispatch_async(queue, ^{
NSLog(@"reading two");
});
dispatch_barrier_async(queue, ^{
NSLog(@"writing");
});
dispatch_async(queue, ^{
NSLog(@"reading three");
});
dispatch_async(queue, ^{
NSLog(@"reading four");
});
dispatch_barrier_async函数与dispatch_queue_create 生成的 Concurrent Dispatch Queue一起使用。
如上所示:dispatch_barrier_async会等到reading one 和 reading two 执行完之后,在执行,而且在writing执行完之后才会执行后面的reading three reading four
4,dispatch_apply
dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API,该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等待全部处理执行结束。
dispatch_apply:第一个参数为重复次数,第二个参数为追加对象的Dispatch Queue,第三个参数为追加的处理。其中第三个参数是是带参数的是为了区分各个block。
5,dispatch_suspend / dispatch_resume
当追加大量处理到Dispatch Queue时,再追加处理的过程中,有时希望不执行已追加的处理。
这种情况下,只要挂起Dispatch Queue即可,当可以执行时再恢复。
dispatch_suspend(queue); //挂起
dispatch_resume(queue); /恢复
6,Dispatch Semaphore
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSMutableArray * arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 10000 ; i ++) {
dispatch_async(queue, ^{
[arr addObject:[NSNumber numberWithInt:i]];
});
}
上面这段代码,由于内存错误导致应用程序异常的概率很高。那么看下面这段正常的代码:
dispatch semaphore 是持有信号的计数,该计数是多线程编程中得计数类型信号,所谓信号,类似于过马路时常用的手旗。可以通过时举起手旗,不可通过时放下手旗。而在dispatch semaphore中,使用计数来实现该功能。计数为0时等待,计数为1或者大于1时,减去1而不等待。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); //初始化值为1
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSMutableArray * arr = [[NSMutableArray alloc] init];
for (int i = 0; i < 10000 ; i ++) {
dispatch_async(queue, ^{
//进行排他控制
//因为semaphore的初始化值为1所以这个不用等待直接执行,但是执行过这句话之后semaphore变成0
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[arr addObject:[NSNumber numberWithInt:i]];
//排他控制结束
//所以通过dispatch_semaphore_signal函数将dispatch semaphore的计数值加1
dispatch_semaphore_signal(semaphore);
});
}
由此可见,在没有Serial Dispatch Queue 和 dispatch_barrier_async函数那么大粒度且一部分处理需要进行排他控制的情况下,Dispatch Semaphore便可发挥威力。