方法调用者希望调用的是一个同步返回的方法,而不是以callback形式携带返回值的方法。
// 同步方法
- (NSInteger)methodSync {
__blockNSIntegerresult =0;
[selfmethodAsync:^(NSIntegervalue) {
result = value;
}];
// 如果result同步返回就好了
returnresult;
}
// 异步方法
- (void)methodAsync:(void(^)(NSIntegerresult))callBack {
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSLog(@"methodAsync 异步开始");
sleep(2);
NSLog(@"methodAsync 异步结束");
if(callBack) {
callBack(5);
}
});
}
iOS编程将异步方法转化为同步方法
dispatch_group可以很方便的管理多个派发任务,并在任务结束时候可以得到回调通知,或者可以一直阻塞线程直到派发组内的所有派发任务都完成
方式一:使用派发组dispatch_group
- (NSInteger)methodSync {
NSLog(@"methodSync 开始");
__blockNSIntegerresult =0;
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[selfmethodAsync:^(NSIntegervalue) {
result = value;
dispatch_group_leave(group);
}];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"methodSync 结束 result:%ld", (long)result);
returnresult;
}
方式二(推荐):使用信号量dispatch_semaphore
dispatch_semaphore通常是用来多线程执行多个并发任务时通过信号量的方式对并发执行数量的限制。当信号量不够(=0)的时候当前调用线程将被阻塞,所以我们可以通过模拟信号量不够的情况来阻塞同步方法的返回,直到方法内部的异步回调之后;
- (NSInteger)methodSync {
NSLog(@"methodSync 开始");
__blockNSIntegerresult =0;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[selfmethodAsync:^(NSIntegervalue) {
result = value;
dispatch_semaphore_signal(sema);
}];
// 这里本来同步方法会立即返回,但信号量=0使得线程阻塞
// 当异步方法回调之后,发送信号,信号量变为1,这里的阻塞将被解除,从而返回正确的结果
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"methodSync 结束 result:%ld", (long)result);
returnresult;
}