dispatch_after
dispatch_after延迟将任务提交到队列中,注意不是事先将任务添加到队列中然后再延迟执行。
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
NSLog(@"任务1,%@", [NSThread currentThread]);
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)), serialQueue, ^{
NSLog(@"5秒后提交该block,%@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"任务2,%@", [NSThread currentThread]);
});
/**
dispatch_time_t
dispatch_time()创建时间
DISPATCH_TIME_NOW从现在开始计算
NSEC_PER_SEC=1秒
*/
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC));
dispatch_after(time, serialQueue, ^{
NSLog(@"2秒后提交该block,%@", [NSThread currentThread]);
});
从打印日志可以看出,所有任务都是添加到串行队列中的,由串行队列的特性可知:先进入对的任务结束,才会执行后面的任务,可验证dispatch_after是将任务延时添加到队列中。
DISPATCH_TIME_NOW是指执行到该行代码时开始计算。
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
NSLog(@"任务1,%@", [NSThread currentThread]);
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)), serialQueue, ^{
NSLog(@"5秒后提交该block,%@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"任务2,%@", [NSThread currentThread]);
sleep(10);
});
/**
dispatch_time_t
dispatch_time()创建时间
DISPATCH_TIME_NOW从现在开始计算
NSEC_PER_SEC=1秒
*/
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC));
dispatch_after(time, serialQueue, ^{
NSLog(@"2秒后提交该block,%@", [NSThread currentThread]);
});
从两次的打印日志中也可以看出,dispatch_after是另外开辟了一条线程执行的。
dispatch_group_t
dispatch_group_t:调度组,可以将队列中的任务放到调度组中,由调度组来控制任务的执行。
dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, concurrentQueue, ^{
NSLog(@"任务1%@", [NSThread currentThread]);
});
dispatch_group_async(group, concurrentQueue, ^{
NSLog(@"任务2%@", [NSThread currentThread]);
});
dispatch_group_async(group, concurrentQueue, ^{
NSLog(@"任务3%@", [NSThread currentThread]);
});
dispatch_group_notify(group, concurrentQueue, ^{
NSLog(@"调度组中concurrentQueue队列的所有任务执行完毕%@", [NSThread currentThread]);
});
- dispatch_group_async:创建一个异步任务将其放在concurrentQueue队列中,并关联到调度组中。
- dispatch_group_notify:concurrentQueue队列中所有关联到调度组中的任务结束时执行。
dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSLog(@"任务1%@", [NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSLog(@"任务2%@", [NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSLog(@"任务3%@", [NSThread currentThread]);
dispatch_group_leave(group);
});
- dispatch_group_enter:任务入组。
- dispatch_group_leave:任务出组。
dispatch_group_enter和dispatch_group_leave需要成对出现。
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC));
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSLog(@"任务1%@", [NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
NSLog(@"任务2%@", [NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
sleep(5);
NSLog(@"任务3%@", [NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_notify(group, concurrentQueue, ^{
NSLog(@"调度组中concurrentQueue队列的所有任务执行完毕%@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_group_wait(group, time);
NSLog(@"顶多等你三秒,调度组不结束我就干自己的事去了");
});
dispatch_group_wait:在指定时间或调度组结束时,执行下面的任务。可以应用在网络请求时间较长时的处理。
dispatch_apply
dispatch_apply:重复提交任务到队列中。
dispatch_apply(10, serialQueue, ^(size_t i) {
NSLog(@"在线程中循环10次执行该block%ld%@", i, [NSThread currentThread]);
});
在当前线程中执行,不会开辟新的线程。
dispatch_apply(10, concurrentQueue, ^(size_t i) {
NSLog(@"在线程中循环10次执行该block%ld%@", i, [NSThread currentThread]);
});
会开辟新的线程,异步执行任务。
其他
- dispatch_queue_get_label:获取队列的名字。
//获取指定队列的名字
NSLog(@"%s", dispatch_queue_get_label(serialQueue));
//获取当前队列的名字
NSLog(@"%s", dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));