多个网络请求的接口设计

最近作到一个页面里有四个接口,每个接口返回都有对应的UI改变,因此要四个接口所有请求返回成功后,再去作UI刷新。然而因为网络请求用的是AFN等第三方库,自己就是异步的,因此GCD的栅栏函数dispatch_barrier_async是没有用的。网络

那么就让他一个一个的执行,等到全部都执行完成后再去刷新UI,因而乎呢,能够在第一个网络请求了的返回block里去作第二个网络请求,以此类推就能够完成最后的UI刷新。这个不失为一种比较有效的方法,可是这样写的代码真的挺丑的。。。。并发

若是单纯的想让这几个网络请求按顺序执行,先进先出,那就是队列啊,iOS里提供的队列管理就是GCD这个强大的c语言实现的库。GCD里面有一个信号量--dispatch_semaphore_t,异步

dispatch_semaphore_t

dispatch_semaphore_create(long value);建立一个信号量,若是value小于0的话,这个信号量就是nil。 dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);可让信号量减1,若是信号量是0,那么他会等待信号量为非零才会执行下一步。 dispatch_semaphore_signal(dispatch_semaphore_t dsema);可让信号量增长1.async

经过这上面的方法,咱们能够一开始设计信号量是0,每个网络请求以前用dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);,请求结束回调里用dispatch_semaphore_signal(dispatch_semaphore_t dsema);这样可让请求按照顺序执行下来。Talk is cheep,show your the code:函数

- (void)semaphoretest {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"任务1完成---- %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"任务2完成---- %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"任务3完成---- %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
}
复制代码

打印结果以下:spa

信号量结果.png

很清楚的看到了他们是按照顺序执行的。线程

dispatch_group

最好的设计固然是他们几个并发执行,到时候所有请求结束后再去作UI的刷新。因而乎想到了CGD的group啦!GCD就是辣么强大有木有!设计以下:设计

- (void)groupTest {
    dispatch_queue_t quete = dispatch_queue_create("XIAXIAQUEUE", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();

    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);
        
            NSLog(@"网络任务1完----%@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任务1完成---%@", [NSThread currentThread]);
    });

//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);
        
            NSLog(@"网络任务2完成----%@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任务2完成---%@", [NSThread currentThread]);
    
    });

//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);
        
            NSLog(@"网络任务3完成 --- %@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任务3完成---- %@", [NSThread currentThread]);
    });



    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"最后执行 ---- %@", [NSThread currentThread]);
    });
}
复制代码

打印的结果以下:3d

group结果.png

首先能够发现其实这几个任务都是在不一样的线程的,可是最后执行的确定是最后一步!code

结束语

做为一个程序猿,思考是最重要的,虽然如今网上不少代码能够用拿来主义,可是若是只会拿来,那只能做为一个初级的程序猿了。因此有时候多思考,多想一想。

相关文章
相关标签/搜索