有那么一个场景如下
+PayWithBlock:(NSString*(^)(NSString *message)) block;
如果 block 返回是同步的那是没有问题的,但是如果block 内容需要网络请求后才能得到,那如何处理,如下
Client { //开始调用 [Pay PayWithBlock:NSString *(^)( NSString *message) { //异步网络请求数据 return @"test"; }]; }
如果不做任何处理是无法得到网络请求的数据结果的, 因此我们在这里需要使用信号量来处理,思路如下:
// 设置一个异步线程组 // 设置一个网络请求 NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]]; // 创建一个信号量为0的信号(红灯) dispatch_semaphore_t sema = dispatch_semaphore_create(0); NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"第一步操作"); // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯) dispatch_semaphore_signal(sema); }]; [task resume]; // 以下还要进行一些其他的耗时操作 NSLog(@"耗时操作继续进行"); // 开启信号等待,设置等待时间为永久,直到信号的信号量大于等于1(绿灯) dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); NSLog(@"dispatch_semaphore_wait_end");
整合一起代码如下:
Client { //开始调用 [Pay PayWithBlock:NSString *(^)( NSString *message) { // 设置一个网络请求 __block NSString *result = nil;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]]; // 创建一个信号量为0的信号(红灯) dispatch_semaphore_t sema = dispatch_semaphore_create(0); NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"第一步操作"); // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯) result = @"我是网络请求数据"; dispatch_semaphore_signal(sema); }]; [task resume]; // 以下还要进行一些其他的耗时操作 NSLog(@"耗时操作继续进行"); // 开启信号等待,设置等待时间为永久,直到信号的信号量大于等于1(绿灯) dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); NSLog(@"dispatch_semaphore_wait_end");
return resutl; }];}
方案二 、使用dispatch_group_enter(group),dispatch_group_leave(group) 待续