- 作用很形象的类似于栅栏,栅栏前面的任务完成之后接着执行栅栏函数中添加的任务,最后执行栅栏后面的任务;
- 栅栏函数只有配合自定义的并发队列才可以发挥作用,如果使用全局队列是发挥不了自身特性的;
/// dispatch_barrier_sync 、dispatch_async 学习(注意:栅栏函数要起作用,那么必须使用dispatch_queue_create函数创建自定义队列,不能使用全局队列)
/// 获取全局队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t conCurrentQueue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_CONCURRENT);
/// 任务1
dispatch_block_t task1 = ^{
NSLog(@"任务1开始执行:%@", [NSThread currentThread]);
sleep(2);
NSLog(@"任务1执行结束:%@", [NSThread currentThread]);
};
/// 任务2
dispatch_block_t task2 = ^{
NSLog(@"任务2开始执行:%@", [NSThread currentThread]);
sleep(2);
NSLog(@"任务2执行结束:%@", [NSThread currentThread]);
};
/// 将任务添加到队列中
dispatch_async(conCurrentQueue, task1);
dispatch_async(conCurrentQueue, task2);
/// 不会创建新的线程,任务在当前线程中执行
dispatch_barrier_sync(conCurrentQueue, ^{
NSLog(@"任务3开始执行:%@", [NSThread currentThread]);
sleep(2);
NSLog(@"任务3执行结束:%@", [NSThread currentThread]);
});
/// 会创建新的线程,任务在新的线程中执行
dispatch_barrier_async(conCurrentQueue, ^{
NSLog(@"任务3开始执行:%@", [NSThread currentThread]);
sleep(2);
NSLog(@"任务3执行结束:%@", [NSThread currentThread]);
});
/// 任务4(该种方式创建的 block 任务无法被取消)
dispatch_block_t task4 = ^{
NSLog(@"任务4开始执行:%@", [NSThread currentThread]);
sleep(2);
NSLog(@"任务4执行结束:%@", [NSThread currentThread]);
};
// 使用 dispatch_block_create() 方式创建的 block 任务可以被取消,前提是被取消的 block 任务还没有被 cpu 调度执行,如果已经被调度执行,那么取消无效
dispatch_block_t task4 = dispatch_block_create(0, ^{
NSLog(@"任务4开始执行:%@", [NSThread currentThread]);
sleep(2);
NSLog(@"任务4执行结束:%@", [NSThread currentThread]);
});
/// 将任务4添加到队列中
dispatch_async(conCurrentQueue, task4);
/// 取消任务4的执行
dispatch_block_cancel(task4);
注意:
- 栅栏函数要想起作用,那么创建任务队列就必须使用
dispatch_queue_create()
该种方式,使用全局队列栅栏函数无法发挥作用; - 使用
dispatch_block_cancel()
方式取消队列中未开始执行的任务时,block 任务的创建方式必须使用dispatch_block_create()
这种方式,同时已经开始执行的任务被取消是不起作用的;