登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

iOS多个网络请求完后执行下一步 [复制链接]

2017-12-18 10:54
James1991 阅读:695 评论:0 赞:2
Tag:  

在开发中,我们很容易遇到这样的需求,需要我们同时做多个网络请求,所有网络请求都完成后才能进行下一步的操作。如下载多个图片,下载完了才能展示。

今天我们就来研究一下这个问题的解决方案。

1.首先,我们创建一个项目,然后做一般性的做法,不做任何处理去连续请求一个接口10次:

先在viewDidLoad中创建第一种情况.

1
2
3
4
5
6
7
//1.无处理
    UIButton *Btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
    Btn1.frame = CGRectMake(10010010040);
    Btn1.backgroundColor = [UIColor grayColor];
    [Btn1 setTitle:@"noConduct" forState:UIControlStateNormal];
    [Btn1 addTarget:self action:@selector(Btn1) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:Btn1];

实现第一种情况的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//1.noConduct
-(void)Btn1{
    NSString *str = @"http://www.jianshu.com/p/6930f335adba";
    NSURL *url = [NSURL URLWithString:str];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSession *session = [NSURLSession sharedSession];
     
    for (int i=0; i<10; i++) {
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
             
            NSLog(@"%d---%d",i,i);
             
        }];
         
        [task resume];
    }
     
    NSLog(@"end");
}

运行,看看我们的控制台输出:

1
2
3
4
5
6
7
8
9
10
11
2017-12-04 17:10:10.503 DownImage[3289:261033] end
2017-12-04 17:10:10.676 DownImage[3289:2610800---0
2017-12-04 17:10:10.704 DownImage[3289:2610801---1
2017-12-04 17:10:10.754 DownImage[3289:2610964---4
2017-12-04 17:10:10.760 DownImage[3289:2610802---2
2017-12-04 17:10:10.800 DownImage[3289:2610965---5
2017-12-04 17:10:10.840 DownImage[3289:2610807---7
2017-12-04 17:10:10.844 DownImage[3289:2610826---6
2017-12-04 17:10:10.846 DownImage[3289:2610963---3
2017-12-04 17:10:10.888 DownImage[3289:2610968---8
2017-12-04 17:10:10.945 DownImage[3289:2610809---9

很明显,无任何处理情况下,end最先被打印出来,由于网络请求的异步回调,然后各个网络请求的回调顺序是无序的。

2.使用GCD的dispatch_group_t

viewDidLoad里:

1
2
3
4
5
6
7
//2.group
    UIButton *Btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
    Btn2.frame = CGRectMake(10020010040);
    Btn2.backgroundColor = [UIColor grayColor];
    [Btn2 setTitle:@"group--" forState:UIControlStateNormal];
    [Btn2 addTarget:self action:@selector(Btn2) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:Btn2];

实现:

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
//2.group--
-(void)Btn2{
    NSString *str = @"http://www.jianshu.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");
    });
}

运行看看控制台输出:

1
2
3
4
5
6
7
8
9
10
11
2017-12-04 17:14:46.984 DownImage[3289:2653742---2
2017-12-04 17:14:46.987 DownImage[3289:2653701---1
2017-12-04 17:14:47.052 DownImage[3289:2653835---5
2017-12-04 17:14:47.065 DownImage[3289:2653704---4
2017-12-04 17:14:47.111 DownImage[3289:2653793---3
2017-12-04 17:14:47.121 DownImage[3289:2653836---6
2017-12-04 17:14:47.169 DownImage[3289:2653837---7
2017-12-04 17:14:47.192 DownImage[3289:2653709---9
2017-12-04 17:14:47.321 DownImage[3289:2653838---8
2017-12-04 17:14:47.747 DownImage[3289:2653740---0
2017-12-04 17:14:47.747 DownImage[3289:261033] end
1
2
3
4
5
6
7
8
9
10
11
2017-12-04 17:15:14.576 DownImage[3289:2659423---3
2017-12-04 17:15:14.626 DownImage[3289:2659362---2
2017-12-04 17:15:14.647 DownImage[3289:2659444---4
2017-12-04 17:15:14.648 DownImage[3289:2659360---0
2017-12-04 17:15:14.657 DownImage[3289:2659431---1
2017-12-04 17:15:14.709 DownImage[3289:2659445---5
2017-12-04 17:15:14.728 DownImage[3289:2659446---6
2017-12-04 17:15:14.734 DownImage[3289:2659447---7
2017-12-04 17:15:14.738 DownImage[3289:2659438---8
2017-12-04 17:15:14.816 DownImage[3289:2659449---9
2017-12-04 17:15:14.816 DownImage[3289:261033] end

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

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

1
2
3
4
5
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

1
2
3
4
5
6
7
//3.semaphore
    UIButton *Btn3 = [UIButton buttonWithType:UIButtonTypeCustom];
    Btn3.frame = CGRectMake(10030010040);
    Btn3.backgroundColor = [UIColor grayColor];
    [Btn3 setTitle:@"semaphore" forState:UIControlStateNormal];
    [Btn3 addTarget:self action:@selector(Btn3) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:Btn3];
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
//3.semaphore--
-(void)Btn3{
    NSString *str = @"http://www.jianshu.com/p/6930f335adba";
    NSURL *url = [NSURL URLWithString:str];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSession *session = [NSURLSession sharedSession];
     
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    for (int i=0; i<10; i++) {
         
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
             
            NSLog(@"%d---%d",i,i);
            count++;
            if (count==10) {
                dispatch_semaphore_signal(sem);
                count = 0;
            }
             
        }];
         
        [task resume];
    }
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
     
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"end");
    });
}

运行看看控制台输出:

1
2
3
4
5
6
7
8
9
10
11
2017-12-04 17:36:49.098 DownImage[3428:2836512---2
2017-12-04 17:36:49.144 DownImage[3428:2842100---0
2017-12-04 17:36:49.152 DownImage[3428:2842133---3
2017-12-04 17:36:49.158 DownImage[3428