说明
在某些情况下,需要对block回调完成进行判断,比如,当需在一个数据筛选方法中,有多个数据类型筛选,最后集合到一个数组或字典中。其中有一个数据类型必须调用接口获取,如果不等待接口完成的话,最后可能因为接口时间差无法加入到最后的数组中。所以必须等待接口完成回调后才能继续执行代码。
使用GCD信号量即可解决该问题。
信号量
// 创建信号量
dispatch_semaphore_create(long value);
// 发送信号量dispatch_semaphore_signal(dispatch_semaphore_t deem);
// 等待信号量
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
使用方法
// 创建信号量
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[Request requestWithSuccess:^(NSArray *accounts) {
// 发送完成信号
dispatch_semaphore_signal(sem);
} error:^(RCErrorCode status) {
}];
// 设置等待时间
dispatch_time_t t = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*5);
// 等待完成信号
dispatch_semaphore_wait(sem, t);
该方法会在block完成后或者5秒后继续执行代码,也可设置成永远等待。
实现异步线程同步操作
在并发队列中,异步线程执行任务完成的顺序是不确定的。虽然可以使用串行队列异步的模式完成该需求,但是任务都会在同一个线程中执行,这样就失去了多核处理的优势。
dispatch_queue_t queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"任务1:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务2:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务3:%@",[NSThread currentThread]);
});
输出结果均在同一线程执行任务
使用GCD信号量实现
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务1:%@",[NSThread currentThread]);
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务2:%@",[NSThread currentThread]);
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务3:%@",[NSThread currentThread]);
});