iOS 网络执行顺序

概述

闲话少说直接开干! 在开发的过程中,相信你会遇到这2个场景,有四个网络需要执行,分别命名为网络A, 网络B, 网络C, 网络D:

1.情况一: 顺序执行不能乱 网络A -->网络B -->网络C -->网络D
a执行完, 执行b
b执行完, 执行c
c执行完, 执行d
2.情况二: 网络a, 网络b, 网络c, 网络d的完成顺序不用管, 但是必须这4个网络都执行完才能执行某一个逻辑(命名为逻辑A)

实现方法

1.情况一: 顺序执行

先看一下正常的调用顺序的返回结果,执行了多次发现网络的返回顺序是随机的提供截图2张
001.png

002.png
- (void)testStart {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        // 网络1
        [self networkRequestOneWith:semaphore];
        
        /* 执行到这个位置的时候信号量是0,所以在此线程中等待 直到信号量大于0的时候 才会执行该语句的下一步 */
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        // 网络2
        [self networkRequestTwoWith:semaphore];
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        // 网络3
        [self networkRequestThreeWith:semaphore];
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        // 网络4
        [self networkRequestFourWith:semaphore];
       
    });
}

- (void)networkRequestOneWith:(dispatch_semaphore_t)semaphore {
    [NetworkManager launchNetworkWithSuccess:^(id responseObject) {
        DLog(@"网络1111成功");
        /* 网络返回成功需要进行下一个网络 此处语句作用是信号量+1 */
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSError *httpError, NSString *appErrorCode, id responseObject) {
    }];
}

只列举出其中一个网络,其他3个网络的写法类似,下面看一下运行结果:


003.png

004.png
2.情况二:多个网络都执行完 再去执行特定的某一个网络

先看一下平时的group的基本使用方法

dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //模拟网络1
        DLog(@"网络1111成功");
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //模拟网络2
        DLog(@"网络2222成功");
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        ///模拟网络3
        DLog(@"网络3333成功");
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        ///模拟网络4
        DLog(@"网络4444成功");
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        DLog(@"网络1 网络2 网络3 网络4 全部执行完毕");
    });

运行看一下效果:


005.png

006.png

确实是我们想象的效果网络1 2 3 4执行完的顺序是随机的并且最后执行的也是我们设置好的逻辑!

上面代码中模拟的位置如果换成真的的网络代码其实就会出现错误,因为网络本身是一个异步过程,所以会导致提前执行我们指定的逻辑 口说无凭 上代码看效果

 dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //模拟网络1
        [NetworkManager launchNetworkWithSuccess:^(id responseObject) {
            DLog(@"网络1111成功");
        } failure:^(NSError *httpError, NSString *appErrorCode, id responseObject) {
        }];
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //模拟网络2
        [NetworkManager launchNetworkWithSuccess:^(id responseObject) {
            DLog(@"网络22222成功");
        } failure:^(NSError *httpError, NSString *appErrorCode, id responseObject) {
        }];
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        ///模拟网络3
        [NetworkManager launchNetworkWithSuccess:^(id responseObject) {
            DLog(@"网络3333成功");
        } failure:^(NSError *httpError, NSString *appErrorCode, id responseObject) {
        }];
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        ///模拟网络4
        [NetworkManager launchNetworkWithSuccess:^(id responseObject) {
            DLog(@"网络44444成功");
        } failure:^(NSError *httpError, NSString *appErrorCode, id responseObject) {
        }];
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        DLog(@"网络1 网络2 网络3 网络4 全部执行完毕");
    });

运行看效果:


007.png

008.png

打印结果一目了然,首先执行了我们原本以为最后执行的代码,所以这么写是不对的

直接上正确代码
- (void)testStart {
    
    dispatch_queue_t quete = dispatch_queue_create("XIAXIAQUEUE", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();

    // 网络1
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        [self networkRequestOneWith:group];
    });

    // 网络2
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        [self networkRequestTwoWith:group];
    });

    // 网络3
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        [self networkRequestThreeWith:group];
    });

    // 网络4
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        [self networkRequestFourWith:group];
    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        DLog(@"网络1 网络2 网络3 网络4 全部执行完毕");
    });
}

- (void)networkRequestOneWith:(dispatch_group_t)group {
    [NetworkManager launchNetworkWithSuccess:^(id responseObject) {
        DLog(@"网络1111成功");
       dispatch_group_leave(group);
    } failure:^(NSError *httpError, NSString *appErrorCode, id responseObject) {
        dispatch_group_leave(group);
    }];
}

运行看效果:


09.png

10.png

结果一目了然不管怎么执行都是最后执行我们要的代码

注意: dispatch_group_enter(group)跟dispatch_group_leave(group)一定是匹配成对的,否则永远进不到最后执行的代码中.

你可能感兴趣的:(iOS 网络执行顺序)