iOS当多个网络请求完成后执行下一步的方法详解

2020-01-21 02:45:01王冬梅

实现:


//2.group--
-(void)Btn2{
 NSString *str = @"http://www.easck.com/p/6930f335adba";
 NSURL *url = [NSURL URLWithString:str];
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
 NSURLSession *session = [NSURLSession sharedSession];
 
 dispatch_group_t downloadGroup = dispatch_group_create();
 for (int i=0; i<10; i++) {
 dispatch_group_enter(downloadGroup);
 
 NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  
  NSLog(@"%d---%d",i,i);
  dispatch_group_leave(downloadGroup);
  
 }];
 
 [task resume];
 }
 
 dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
 NSLog(@"end");
 });
}

运行看看控制台输出:


2017-12-04 17:14:46.984 DownImage[3289:265374] 2---2
2017-12-04 17:14:46.987 DownImage[3289:265370] 1---1
2017-12-04 17:14:47.052 DownImage[3289:265383] 5---5
2017-12-04 17:14:47.065 DownImage[3289:265370] 4---4
2017-12-04 17:14:47.111 DownImage[3289:265379] 3---3
2017-12-04 17:14:47.121 DownImage[3289:265383] 6---6
2017-12-04 17:14:47.169 DownImage[3289:265383] 7---7
2017-12-04 17:14:47.192 DownImage[3289:265370] 9---9
2017-12-04 17:14:47.321 DownImage[3289:265383] 8---8
2017-12-04 17:14:47.747 DownImage[3289:265374] 0---0
2017-12-04 17:14:47.747 DownImage[3289:261033] end

2017-12-04 17:15:14.576 DownImage[3289:265942] 3---3
2017-12-04 17:15:14.626 DownImage[3289:265936] 2---2
2017-12-04 17:15:14.647 DownImage[3289:265944] 4---4
2017-12-04 17:15:14.648 DownImage[3289:265936] 0---0
2017-12-04 17:15:14.657 DownImage[3289:265943] 1---1
2017-12-04 17:15:14.709 DownImage[3289:265944] 5---5
2017-12-04 17:15:14.728 DownImage[3289:265944] 6---6
2017-12-04 17:15:14.734 DownImage[3289:265944] 7---7
2017-12-04 17:15:14.738 DownImage[3289:265943] 8---8
2017-12-04 17:15:14.816 DownImage[3289:265944] 9---9
2017-12-04 17:15:14.816 DownImage[3289:261033] end

从上两次输出可以看出,end确实是在所有网络请求之后才输出出来,这也是符合了我们的需求。

代码中我们只添加了4行代码


dispatch_group_t downloadGroup = dispatch_group_create();
dispatch_group_enter(downloadGroup);
dispatch_group_leave(downloadGroup);
dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
 });

对以上4行代码可理解为:创建一个dispatch_group_t, 每次网络请求前先dispatch_group_enter,请求回调后再dispatch_group_leave,对于enter和leave必须配合使用,有几次enter就要有几次leave,否则group会一直存在。当所有enter的block都leave后,会执行dispatch_group_notify的block。

3.使用GCD的信号量dispatch_semaphore_t


//3.semaphore
 UIButton *Btn3 = [UIButton buttonWithType:UIButtonTypeCustom];
 Btn3.frame = CGRectMake(100, 300, 100, 40);
 Btn3.backgroundColor = [UIColor grayColor];
 [Btn3 setTitle:@"semaphore" forState:UIControlStateNormal];
 [Btn3 addTarget:self action:@selector(Btn3) forControlEvents:UIControlEventTouchUpInside];
 [self.view addSubview:Btn3];