等待多个网络请求一起返回

等待多个任务全部完成首先想到的是使用dispatch_group,但是dispatch_group是等待多个同步任务一起完成,当任务是异步的网络请求时,dispatch_group便不起作用。可以使用信号量来解决这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 网络请求模拟
- (void)httpRequest:(NSString *)method param:(NSDictionary *)param completion:(void(^)(id response))block {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *command = [param objectForKey:@"commandKey"];
NSLog(@"request: %@ run in thread: %@", command, [NSThread currentThread]);
NSTimeInterval sleepInterval = arc4random() % 10;
[NSThread sleepForTimeInterval:sleepInterval];

dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"request: %@ done!", command);
block(nil);
});
});
}

- (void)testUsingSemphore {
dispatch_semaphore_t sem = dispatch_semaphore_create(0);

NSArray *commandArray = @[@"requestcommand1", @"requestcommand2", @"requestcommand3", @"requestcommand4", @"requestcommand5"];
__block NSInteger httpFinishedCount = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[commandArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self httpRequest:nil param:@{@"commandKey": obj} completion:^(id response) {
NSLock *lock = [[NSLock alloc] init];
[lock lock];
if (++httpFinishedCount == [commandArray count]) {
dispatch_semaphore_signal(sem);
}
[lock unlock];
}];
}];

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"所有任务都已经完成了!");
});

}

打印结果:

1
2
3
4
5
6
7
8
9
10
11
2017-06-01 17:23:15.405 Test456[17812:2801931] request: requestcommand1 run in thread: <NSThread: 0x608000268100>{number = 5, name = (null)}
2017-06-01 17:23:15.405 Test456[17812:2802100] request: requestcommand3 run in thread: <NSThread: 0x60800007f480>{number = 7, name = (null)}
2017-06-01 17:23:15.405 Test456[17812:2802099] request: requestcommand2 run in thread: <NSThread: 0x618000263d80>{number = 6, name = (null)}
2017-06-01 17:23:15.405 Test456[17812:2802101] request: requestcommand4 run in thread: <NSThread: 0x60800046c700>{number = 8, name = (null)}
2017-06-01 17:23:15.405 Test456[17812:2802102] request: requestcommand5 run in thread: <NSThread: 0x618000266ac0>{number = 9, name = (null)}
2017-06-01 17:23:15.405 Test456[17812:2801803] request: requestcommand1 done!
2017-06-01 17:23:16.409 Test456[17812:2801803] request: requestcommand5 done!
2017-06-01 17:23:19.410 Test456[17812:2801803] request: requestcommand2 done!
2017-06-01 17:23:22.406 Test456[17812:2801803] request: requestcommand4 done!
2017-06-01 17:23:23.410 Test456[17812:2801803] request: requestcommand3 done!
2017-06-01 17:23:23.411 Test456[17812:2801929] 所有任务都已经完成了!