1、延迟执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 1秒后异步执行这里的代码...
});
2、后台执行
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// something
});
3、主线程执行
dispatch_async(dispatch_get_main_queue(), ^{
// something
});
4、并发执行迭代循环
//GCD提供了一个简化方法叫做dispatch_apply,当我们把这个方法放到并发队列中执行时,这个函数会调用单一block多次,并平行运算,然后等待所有运算结束。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(count, queue, ^(size_t i) {
NSLog("%d",i);
});
5、挂起和恢复队列
//有时候,我们不想让队列中的某些任务马上执行,这时我们可以通过挂起操作来阻止一个队列中将要执行的任务。当需要挂起队列时,使用dispatch_suspend方法;恢复队列时,使用dispatch_resume方法。调用dispatch_suspend会增加队列挂起的引用计数,而调用dispatch_resume则会减少引用计数,当引用计数大于0时,队列会保持挂起状态。因此,这队列的挂起和恢复中,我们需要小心使用以避免引用计数计算错误的出现。
dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
//挂起队列
dispatch_suspend(myQueue);
//恢复队列
dispatch_resume(myQueue);
//执行挂起操作不会对已经开始执行的任务起作用,它仅仅只会阻止将要进行但是还未开始的任务。
6、信号量:在程序开发中,有时候我们不想使用异步方式,例如我们想要调用函数后立刻获取结果值的时候,然后进行后续的数据操作。 这个时候需要信号量来等待返回结果,然后等到结果返回,从而进行后续处理。
信号量的作用是控制多个任务对有限数量资源的访问。一个dispatch semaphore就像一个普通信号的例外。当资源可用时,获取dispatch semaphore的时间比获取传统的系统信号量要更少。这是因为GCD不调用这个特殊情况下的内核。唯一的一次需要在内核中调用的情况是,当资源不可用且系统需要在停止你的线程直到获取信号。举例来说更容易理解,如果你创建了一个有着两个资源的信号量,那同时最多只能有两个线程可以访问临界区。其他想使用资源的线程必须在FIFO队列里等待。
// 创建一个信号量
dispatch_semaphore_t fd_sema = dispatch_semaphore_create(0);
// 等待一个空闲的文件描述符
dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER);
fd = open("/etc/services", O_RDONLY);
// 当完成时,释放掉文件描述符
close(fd);
dispatch_semaphore_signal(fd_sema);
7、创建单例模式
+ (LYServiceInterface *) shareacWebService {
static LYServiceInterface *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[LYServiceInterface alloc] init];
});
return sharedInstance;
}
8、倒计时
__block NSInteger timeOut = 60;//倒计时时间
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1*NSEC_PER_SEC, 0);//每秒执行
self.getCodeBtn.userInteractionEnabled = false;
dispatch_source_set_event_handler(_timer, ^{
if (timeOut <= 0) {
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
//设置时间
[self.getCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal];
self.getCodeBtn.userInteractionEnabled = true;
});
} else {
NSString *strTime = [NSString stringWithFormat:@"%ld 秒",(long)timeOut];
dispatch_async(dispatch_get_main_queue(), ^{
[self.getCodeBtn setTitle:strTime forState:UIControlStateNormal];
});
timeOut--;
}
});
dispatch_resume(_timer);
Dispatch groups是阻塞线程直到一个或多个任务完成的一种方式。在那些需要等待任务完成才能执行某个处理的时候,你可以使用这个方法。Dispatch Group会在整个组的任务都完成时通知你,这些任务可以是同步的,也可以是异步的,即便在不同的队列也行。而且在整个组的任务都完成时,Dispatch Group可以用同步的或者异步的方式通知你。当group中所有的任务都完成时,GCD 提供了两种通知方式。
9、异步执行2个耗时操作,等2个异步操作都执行完毕,再回到主线程执行操作
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的异步操作都执行完毕后,回到主线程...
});
10、dispatch_group_wait。它会阻塞当前线程,直到组里面所有的任务都完成或者等到某个超时发生。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
// 添加队列到组中
dispatch_group_async(group, queue, ^{
// 一些异步操作
});
//如果在所有任务完成前超时了,该函数会返回一个非零值。
//你可以对此返回值做条件判断以确定是否超出等待周期;
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// 不需要group后将做释放操作
dispatch_release(group);